import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; /** *

Netrand Project

*

Software Engineering - CS536

*

University of Wisconsin - Milwaukee

*

Authors:

* *
File: PingRandomness.java *
*

* PingRandomness uses the UNIX ping command as a source for a small set of * random bits. The ping program is asked to send at least 8 datagram packets * to the host given as an argument to PingRandomness. PingRandomness keeps * track of the round-trip times for each packet sent. From these times, a * small amount of entropy can be gained. Using only the decimal portion * of the times, a 1 bit is recorded if it is an even number, otherwise a 0 * bit is recored. A total of 8 bits or 1 byte of entropy is obtained. The * PingRandomness class then uses the BitSender * class to transfer the byte to a server. */ public class PingRandomness extends Thread { // ------- Class Variables -------- // /** * sends the random bytes to a server specified by * BitSenderPrefs */ private BitSender bitSender; // -------------------------------- // /** * holds the command to execute the ping command: * ping -n -c 10 [target_host] */ private String pingCommandLine; // ------- Class Methods ---------- // /** * This is the method that is called when this class is involked from the * command line. It takes one argument from the command line that * corresponds to the name of the host to ping. */ public static void main( String[] args ) { if ( args.length != 1 ) { System.err.println( "Pinger [ping_host]" ); System.exit(1); } try { PingRandomness pr = new PingRandomness(args[0]); pr.start(); } catch ( Exception e ) { System.err.println(e); System.exit(1); } } // --------------------------------- // /** * Constructor for the PingRandomness class. * Constructor initializes the BitSender class object for communication * with the server. It also initializes the classes pingCommandLine * variable to: ping -n -c 10 [target_host]. * @param targetHost - the host to ping * @exception Exception is thrown if complications arise when initializing * the BitSender object. */ public PingRandomness( String targetHost ) throws Exception { bitSender = new BitSender( ); pingCommandLine = "ping -n -c 10 " + targetHost; } // --------------------------------- // /** * Overrides the Thread class's run() method. * Responsible for calling all of the subtasks for obtaining entropy from * calling the ping command and sending results to the server. */ public void run() { try { byte someBits = getPingBits(); bitSender.SendByte(someBits); } catch ( Exception e ) { System.err.println( e ); } stop(); } // ---------------------------------- // /** * Creates a process to execute the ping command, records the round-trip * times for the packets sent by ping, and calls mineBitsFromTimes() method * to mine entropy from the recorded times which are returned to the * original calling method. * @return a byte of random bits * @exception Exception is thrown if an error results from: executing the * ping command or if there were not enough ping times collected to get * a sufficient amount of entropy. */ private byte getPingBits() throws Exception { String pingLine = new String(); Float[] pingTimes = new Float[10]; int index = 0; BufferedReader in = null; try { Process p = Runtime.getRuntime().exec( pingCommandLine ); in = new BufferedReader(new InputStreamReader(p.getInputStream())); while ( (pingLine = in.readLine()) != null ) { if ( pingLine.lastIndexOf("time=") >= 0 ) { String tmp = pingLine.substring(pingLine.lastIndexOf("=")); tmp = tmp.substring(1,tmp.lastIndexOf(" ms")); pingTimes[index++] = Float.valueOf(tmp); } if ( pingLine.indexOf( "---" ) >= 0 ) break; } in.close(); p.destroy(); } catch (IOException e) { System.err.println( e ); throw new Exception(); } if ( index < 8 ) throw new Exception( "not enought ping times collected" ); return ( mineBitsFromTimes(pingTimes, index) ); } // ----------------------- // /** * Mines entropy from the round-trip times recorded from the pinging a host. * Entropy is obtained by taking the decimal portion of the round-trip * times and recording a 1 bit if it is even, otherwise a 0 bit. * @param times - an array of round-trip times * @param numTimes - the number of round-trip times in the array * @return a byte of random bits */ private byte mineBitsFromTimes( Float[] times, int numTimes ) { StringBuffer randomBits = new StringBuffer(); for ( int i = 0; i < 8; i++ ) { float time = (times[i].floatValue()*1000) - (times[i].intValue()*1000); if ( (int)time % 2 == 0 ) randomBits.append("0"); else randomBits.append("1"); } return ( (byte)Integer.parseInt(randomBits.toString(),2) ); } }