|
From: Peter P. <pr...@us...> - 2006-11-23 15:51:58
|
Update of /cvsroot/pyxida/Pyxida/src/edu/harvard/syrah/pyxida/ping In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24820/src/edu/harvard/syrah/pyxida/ping Modified Files: TCPSynPinger.java ICMPPinger.java PingerIF.java PingManager.java UDPAppPinger.java Log Message: Tried to get ICMPPinger to work. It's almost there. It now pings reliably but I couldn't figure out how to extract the timestamps from the packets. Just using System.currentTimeMillis() doesn't work because the packet might have been captured a while ago before Jpcap passes it to Java. I sent an email to the Jpcap author, perhaps he can help. Index: PingManager.java =================================================================== RCS file: /cvsroot/pyxida/Pyxida/src/edu/harvard/syrah/pyxida/ping/PingManager.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** PingManager.java 22 Nov 2006 18:46:44 -0000 1.3 --- PingManager.java 23 Nov 2006 15:51:55 -0000 1.4 *************** *** 6,11 **** import edu.harvard.syrah.prp.Log; import edu.harvard.syrah.sbon.async.CBResult; - import edu.harvard.syrah.sbon.async.CallbacksIF.CB; import edu.harvard.syrah.sbon.async.CallbacksIF.CB0; import edu.harvard.syrah.sbon.comm.AddressFactory; import edu.harvard.syrah.sbon.comm.AddressIF; --- 6,11 ---- import edu.harvard.syrah.prp.Log; import edu.harvard.syrah.sbon.async.CBResult; import edu.harvard.syrah.sbon.async.CallbacksIF.CB0; + import edu.harvard.syrah.sbon.async.CallbacksIF.CB1; import edu.harvard.syrah.sbon.comm.AddressFactory; import edu.harvard.syrah.sbon.comm.AddressIF; *************** *** 20,25 **** private Set<PingerIF> pingerSet = new HashSet<PingerIF>(); ! public void init(CB0 cbDone) { ! AddressFactory.createResolved(DEFAULT_PING_HOSTNAME, new CB<AddressIF>() { protected void cb(CBResult result, AddressIF addr) { PingManager.this.defaultPingAddr = addr; --- 20,25 ---- private Set<PingerIF> pingerSet = new HashSet<PingerIF>(); ! public void init(final CB0 cbDone) { ! AddressFactory.createResolved(DEFAULT_PING_HOSTNAME, new CB1<AddressIF>() { protected void cb(CBResult result, AddressIF addr) { PingManager.this.defaultPingAddr = addr; *************** *** 29,33 **** PingerIF pinger = new ICMPPinger(); pingerSet.add(pinger); ! pinger.init(defaultPingAddr); } --- 29,33 ---- PingerIF pinger = new ICMPPinger(); pingerSet.add(pinger); ! pinger.init(defaultPingAddr, cbDone); } *************** *** 37,41 **** } ! public void addPingReq(AddressIF nodeA, AddressIF nodeB, CB<Double> cbMeasurement) { // TODO implement me } --- 37,41 ---- } ! public void addPingReq(AddressIF nodeA, AddressIF nodeB, CB1<Double> cbMeasurement) { // TODO implement me } Index: ICMPPinger.java =================================================================== RCS file: /cvsroot/pyxida/Pyxida/src/edu/harvard/syrah/pyxida/ping/ICMPPinger.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ICMPPinger.java 22 Nov 2006 18:46:44 -0000 1.2 --- ICMPPinger.java 23 Nov 2006 15:51:55 -0000 1.3 *************** *** 6,13 **** import java.net.InetAddress; import java.net.MalformedURLException; - import java.net.URL; import java.util.Arrays; import jpcap.JpcapCaptor; import jpcap.NetworkInterface; import jpcap.NetworkInterfaceAddress; --- 6,13 ---- import java.net.InetAddress; import java.net.MalformedURLException; import java.util.Arrays; import jpcap.JpcapCaptor; + import jpcap.JpcapSender; import jpcap.NetworkInterface; import jpcap.NetworkInterfaceAddress; *************** *** 16,21 **** --- 16,26 ---- import jpcap.packet.IPPacket; import jpcap.packet.Packet; + import edu.harvard.syrah.prp.ANSI; import edu.harvard.syrah.prp.Log; import edu.harvard.syrah.prp.POut; + import edu.harvard.syrah.sbon.async.CBResult; + import edu.harvard.syrah.sbon.async.EventLoop; + import edu.harvard.syrah.sbon.async.CallbacksIF.CB0; + import edu.harvard.syrah.sbon.async.CallbacksIF.CB1; import edu.harvard.syrah.sbon.comm.AddressFactory; import edu.harvard.syrah.sbon.comm.AddressIF; *************** *** 24,28 **** private static final Log log = new Log(ICMPPinger.class); ! public void init(AddressIF defaultPingAddr) { this.localAddr = AddressFactory.createLocalAddress(); this.defaultPingAddr = defaultPingAddr; --- 29,36 ---- private static final Log log = new Log(ICMPPinger.class); ! private AddressIF pingAddr; ! private CB1<Double> cbPing; ! ! public void init(AddressIF defaultPingAddr, final CB0 cbDone) { this.localAddr = AddressFactory.createLocalAddress(); this.defaultPingAddr = defaultPingAddr; *************** *** 33,41 **** log.debug("devices=" + POut.toString(devices)); ! assert devices.length > 0; ! ! nextDevice: for (int i = 0; i < devices.length; i++) { ! log.debug("Opening new device " + devices[i]); try { --- 41,50 ---- log.debug("devices=" + POut.toString(devices)); ! if (devices.length == 0) ! log.error("This must be run as root."); ! ! nextDevice: for (int i = 0; i < devices.length; i++) { ! log.debug("Opening new device " + devices[i]); try { *************** *** 46,57 **** } - log.debug("Device opened successfully."); device = devices[i]; ! if (device.loopback) { log.debug("Ignoring loopback device."); captor.close(); continue; ! } for (NetworkInterfaceAddress addr : device.addresses) --- 55,66 ---- } device = devices[i]; ! log.debug("Device opened successfully."); ! if (device.loopback) { log.debug("Ignoring loopback device."); captor.close(); continue; ! } for (NetworkInterfaceAddress addr : device.addresses) *************** *** 61,68 **** break; } ! //obtain MAC address of the default gateway ! InetAddress pingAddr = ICMPPinger.this.defaultPingAddr.getInetAddress(); ! captor.setFilter("tcp and dst host " + pingAddr.getHostAddress(), true); InputStream is = null; Packet ping = null; --- 70,86 ---- break; } + + if (thisIP == null) { + log.debug("Local addr not found"); + captor.close(); + continue; + } ! // Obtain MAC address of the default gateway ! InetAddress pingAddr = ICMPPinger.this.defaultPingAddr ! .getInetAddress(); ! log.debug("defaultPingAddr=" + pingAddr); ! captor.setFilter("icmp and dst host " + pingAddr.getHostAddress(), ! false); InputStream is = null; Packet ping = null; *************** *** 71,78 **** try { log.debug("Trying to open web connection"); ! is = new URL("http://www.google.com").openStream(); log.debug("Waiting for packet..."); ping = captor.getPacket(); ! is.close(); } catch (MalformedURLException e) { log.error(e.toString()); --- 89,96 ---- try { log.debug("Trying to open web connection"); ! pingAddr.isReachable(1); log.debug("Waiting for packet..."); ping = captor.getPacket(); ! //captor.setFilter("not", true); } catch (MalformedURLException e) { log.error(e.toString()); *************** *** 83,90 **** if (ping == null) { log.warn("Cannot obtain MAC address of default gateway."); ! captor.close(); continue nextDevice; ! } else if (Arrays.equals(((EthernetPacket) ping.datalink).dst_mac, device.mac_address)) continue; gwMAC = ((EthernetPacket) ping.datalink).dst_mac; log.debug("gwMAC=" + POut.toString(gwMAC)); --- 101,111 ---- if (ping == null) { log.warn("Cannot obtain MAC address of default gateway."); ! captor.close(); continue nextDevice; ! } else if (Arrays.equals(((EthernetPacket) ping.datalink).dst_mac, ! device.mac_address)) { ! log.debug("doing it again"); continue; + } gwMAC = ((EthernetPacket) ping.datalink).dst_mac; log.debug("gwMAC=" + POut.toString(gwMAC)); *************** *** 97,118 **** sender = captor.getJpcapSenderInstance(); sendICMP(ICMPPinger.this.defaultPingAddr); ICMPPinger.this.run(); } }; ! thread.start(); } ! public double ping(AddressIF remoteNode) throws UnsupportedOperationException { ! sendICMP(remoteNode); ! return 0.0; } ! public double ping(AddressIF nodeA, AddressIF nodeB) throws UnsupportedOperationException { throw new UnsupportedOperationException(); } ! private void sendICMP(AddressIF addr) { log.debug("Sending ICMP ping to " + addr); --- 118,152 ---- sender = captor.getJpcapSenderInstance(); sendICMP(ICMPPinger.this.defaultPingAddr); + receiveICMP(); + + log.debug("ICMPPinger initalised."); + // TODO we need to wake up the selector here because it's sleeping in another thread. + + EventLoop.get().registerTimerCB(cbDone); + ICMPPinger.this.run(); } }; ! thread.start(); } ! public void ping(AddressIF remoteNode, CB1<Double> cbPing) throws UnsupportedOperationException { ! this.pingAddr = remoteNode; ! this.cbPing = cbPing; ! synchronized(thread) { ! thread.notify(); ! } } ! public void ping(AddressIF nodeA, AddressIF nodeB, CB1<Double> cbPing) ! throws UnsupportedOperationException { throw new UnsupportedOperationException(); } ! private long sendICMP(AddressIF addr) { ! assert device != null; ! log.debug("Sending ICMP ping to " + addr); *************** *** 121,126 **** icmp.seq = 100; icmp.id = 0; ! icmp.setIPv4Parameter(0, false, false, false, 0, false, false, false, 0, 0, 100, ! IPPacket.IPPROTO_ICMP, thisIP, addr.getInetAddress()); icmp.data = "data".getBytes(); --- 155,160 ---- icmp.seq = 100; icmp.id = 0; ! icmp.setIPv4Parameter(0, false, false, false, 0, false, false, false, 0, 0, ! 100, IPPacket.IPPROTO_ICMP, thisIP, addr.getInetAddress()); icmp.data = "data".getBytes(); *************** *** 130,134 **** ether.dst_mac = gwMAC; icmp.datalink = ether; ! try { sender.sendPacket(icmp); --- 164,168 ---- ether.dst_mac = gwMAC; icmp.datalink = ether; ! try { sender.sendPacket(icmp); *************** *** 136,142 **** log.warn("Failed sending packet: " + e); } } ! ! private void receiveICMP() { ICMPPacket p = (ICMPPacket) captor.getPacket(); log.debug("Received ICMP packet: " + p); --- 170,180 ---- log.warn("Failed sending packet: " + e); } + log.debug("sendPacket=" + icmp); + return System.currentTimeMillis(); } ! ! private long receiveICMP() { ! long recvTS = -1; ! ICMPPacket p = (ICMPPacket) captor.getPacket(); log.debug("Received ICMP packet: " + p); *************** *** 148,157 **** } else if (p.type == ICMPPacket.ICMP_UNREACH) { p.src_ip.getHostName(); ! log.debug("ICMP_UNREACH: " + p.src_ip); } else if (p.type == ICMPPacket.ICMP_ECHOREPLY) { p.src_ip.getHostName(); ! log.debug("ICMP_ECHOREPLY: " + p.src_ip); } log.debug("Finished receiveICMP"); } --- 186,201 ---- } else if (p.type == ICMPPacket.ICMP_UNREACH) { p.src_ip.getHostName(); ! log.debug("ICMP_UNREACH: " + p.src_ip.toString()); } else if (p.type == ICMPPacket.ICMP_ECHOREPLY) { p.src_ip.getHostName(); ! long sec = p.sec; ! long usec = p.usec; ! log.debug("ICMP_ECHOREPLY: " + p.src_ip + " sec=" + sec + " usec=" + usec); ! recvTS = (sec * 1000) + (long) (usec / 1000.0); ! log.debug("recvTS=" + recvTS); ! log.debug("recvSY=" + System.currentTimeMillis()); } log.debug("Finished receiveICMP"); + return recvTS; } *************** *** 159,174 **** try { while (!thread.isInterrupted()) { ! ! receiveICMP(); ! synchronized (thread) { thread.wait(); } ! ! // TODO do useful stuff here, i.e. wait for incoming ping and match it to the request ping ! } ! } catch (InterruptedException e) { /* ignore */ ! } } --- 203,228 ---- try { while (!thread.isInterrupted()) { ! synchronized (thread) { thread.wait(); } ! ! if (pingAddr != null) { ! captor.setFilter("icmp and dst host" + pingAddr.getHostname(), true); ! long sendTS = sendICMP(pingAddr); ! log.debug("sendTS=" + sendTS); ! assert sendTS > 0; ! long recvTS = receiveICMP(); ! assert recvTS > 0; ! final long lat = recvTS - sendTS; ! pingAddr = null; ! EventLoop.get().registerTimerCB(new CB0() { ! protected void cb(CBResult resultOK) { ! cbPing.call(resultOK, (double) lat); ! } ! }); ! } } ! } catch (InterruptedException e) { /* ignore */ } } *************** *** 178,180 **** --- 232,292 ---- } + public static void main(final String[] args) { + ANSI.use(true); + Log.setPackageRoot(ICMPPinger.class); + + EventLoop.set(new EventLoop()); + + if (args.length == 0) { + System.out.println("usage: ICMPPinger <hostname>"); + System.exit(1); + } + + final PingerIF pinger = new ICMPPinger(); + + EventLoop.get().registerTimerCB(new CB0() { + protected void cb(CBResult resultOK) { + AddressFactory.createResolved("www.google.com", new CB1<AddressIF>() { + protected void cb(CBResult result, AddressIF defaultAddr) { + switch (result.state) { + case OK: { + pinger.init(defaultAddr, new CB0() { + protected void cb(CBResult arg0) { + AddressFactory.createResolved(args[0], new CB1<AddressIF>() { + protected void cb(CBResult result, AddressIF addr) { + switch (result.state) { + case OK: { + System.out.println("Pinging addr=" + addr + " "); + pinger.ping(addr, new CB1<Double>() { + protected void cb(CBResult arg0, Double lat) { + System.out.println("lat=" + lat); + } + }); + break; + } + case ERROR: + case TIMEOUT: { + log.error(result.what); + } + } + } + }); + } + }); + break; + } + case ERROR: + case TIMEOUT: { + log.error(result.what); + } + } + } + }); + } + }); + + EventLoop.get().main(); + + } + } Index: TCPSynPinger.java =================================================================== RCS file: /cvsroot/pyxida/Pyxida/src/edu/harvard/syrah/pyxida/ping/TCPSynPinger.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** TCPSynPinger.java 21 Nov 2006 21:14:59 -0000 1.1 --- TCPSynPinger.java 23 Nov 2006 15:51:55 -0000 1.2 *************** *** 2,5 **** --- 2,7 ---- import edu.harvard.syrah.prp.Log; + import edu.harvard.syrah.sbon.async.CallbacksIF.CB0; + import edu.harvard.syrah.sbon.async.CallbacksIF.CB1; import edu.harvard.syrah.sbon.comm.AddressIF; *************** *** 32,34 **** --- 34,51 ---- } + public void init(AddressIF defaultPingAddr, CB0 cbDone) { + // TODO Auto-generated method stub + + } + + public void ping(AddressIF remoteNode, CB1<Double> cbPing) throws UnsupportedOperationException { + // TODO Auto-generated method stub + + } + + public void ping(AddressIF nodeA, AddressIF nodeB, CB1<Double> cbPing) throws UnsupportedOperationException { + // TODO Auto-generated method stub + + } + } Index: UDPAppPinger.java =================================================================== RCS file: /cvsroot/pyxida/Pyxida/src/edu/harvard/syrah/pyxida/ping/UDPAppPinger.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** UDPAppPinger.java 22 Nov 2006 18:46:44 -0000 1.2 --- UDPAppPinger.java 23 Nov 2006 15:51:55 -0000 1.3 *************** *** 2,5 **** --- 2,7 ---- import edu.harvard.syrah.prp.Log; + import edu.harvard.syrah.sbon.async.CallbacksIF.CB0; + import edu.harvard.syrah.sbon.async.CallbacksIF.CB1; import edu.harvard.syrah.sbon.comm.AddressIF; *************** *** 32,34 **** --- 34,51 ---- } + public void init(AddressIF defaultPingAddr, CB0 cbDone) { + // TODO Auto-generated method stub + + } + + public void ping(AddressIF remoteNode, CB1<Double> cbPing) throws UnsupportedOperationException { + // TODO Auto-generated method stub + + } + + public void ping(AddressIF nodeA, AddressIF nodeB, CB1<Double> cbPing) throws UnsupportedOperationException { + // TODO Auto-generated method stub + + } + } Index: PingerIF.java =================================================================== RCS file: /cvsroot/pyxida/Pyxida/src/edu/harvard/syrah/pyxida/ping/PingerIF.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PingerIF.java 21 Nov 2006 21:14:59 -0000 1.1 --- PingerIF.java 23 Nov 2006 15:51:55 -0000 1.2 *************** *** 1,4 **** --- 1,6 ---- package edu.harvard.syrah.pyxida.ping; + import edu.harvard.syrah.sbon.async.CallbacksIF.CB0; + import edu.harvard.syrah.sbon.async.CallbacksIF.CB1; import edu.harvard.syrah.sbon.comm.AddressIF; *************** *** 9,17 **** * */ ! public void init(AddressIF defaultPingAddr); ! public double ping(AddressIF remoteNode) throws UnsupportedOperationException; ! public double ping(AddressIF nodeA, AddressIF nodeB) throws UnsupportedOperationException; public void shutdown(); --- 11,19 ---- * */ ! public void init(AddressIF defaultPingAddr, CB0 cbDone); ! public void ping(AddressIF remoteNode, CB1<Double> cbPing) throws UnsupportedOperationException; ! public void ping(AddressIF nodeA, AddressIF nodeB, CB1<Double> cbPing) throws UnsupportedOperationException; public void shutdown(); |