Created
December 15, 2012 05:31
-
-
Save anonymous/4291527 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package fr.esial.tcpdump; | |
import fr.esial.smartshare.PacketViewer; | |
import java.io.BufferedReader; | |
import java.io.DataInputStream; | |
import java.io.DataOutputStream; | |
import java.io.File; | |
import java.io.FileReader; | |
import java.io.IOException; | |
import java.util.Timer; | |
import java.util.TimerTask; | |
import android.util.Log; | |
/** | |
* | |
* This class is responsible for the scanning process. | |
* It launches tcpdump and reads the output. | |
* Tcpdump is launched in a separate process, output is redirected to a file. | |
* One thread reads output file and puts packets in a buffer. | |
* An other thread periodically send data contained in the buffer to the UI | |
* @author Armel | |
* | |
*/ | |
public class TCPDump { | |
//Boolean to indicate if the scanning process is runing or not | |
private boolean isStarted; | |
/************************* tcpdump ***********************/ | |
//The command to launch tcpdump | |
private final String commande="/data/local/tcpdump-arm -l -i eth0 > /data/local/output.txt\n"; | |
//The Processes wherein tcpdump will be exec | |
private Process process; | |
//The pid of the tcpdump process | |
private int pid; | |
//The buffer in which the captured packets will be put | |
private Buffer buffer; | |
//The buffer size | |
private int size=256; | |
//A timer to manage the tcpdump launch | |
private Timer tcpdumpTimer; | |
//The timer task to create a process and exec tcpdump on it | |
private TimerTask tcpdump; | |
/********************* Reader Thread ********************/ | |
//The thread that read the output file of tcpdup | |
private Thread readThread; | |
//The output file of tcpdump | |
private File dumpedFile; | |
//A buffered reader to read the file | |
private BufferedReader reader; | |
/********************* Display Thread ********************/ | |
//A timer to manage the displaying task | |
private Timer displayTimer; | |
//A timer task that periodically reads the buffer and sends packet to the UI | |
private TimerTask displayThread; | |
//An helper object to read the buffer | |
private BufferReader bufferReader; | |
//Activity representing UI | |
private PacketViewer viewer; | |
/**********************************************************/ | |
/** | |
* @param packetViewer The activity that manage packets UI | |
*/ | |
public TCPDump(PacketViewer packetViewer) { | |
super(); | |
buffer=Buffer.getInstance(size); | |
this.isStarted = false; | |
this.viewer = packetViewer; | |
this.bufferReader = new BufferReader(size,viewer); | |
init(); | |
} | |
/** | |
* Init threads, process and timer task used for the scanning process | |
*/ | |
private void init(){ | |
//Init the timer task that create the process and launch tcpdump on it | |
tcpdump=new TimerTask(){ | |
public void run(){ | |
try { | |
//create a process with root privilege, tcpdump require root | |
process = Runtime.getRuntime().exec("su"); | |
DataOutputStream os = new DataOutputStream(process.getOutputStream()); | |
os.writeBytes(commande); | |
os.flush(); | |
os.writeBytes("exit\n"); | |
os.flush(); | |
os.close(); | |
//sleep 1 second to ensure that the new process is listed by the system | |
Thread.sleep(1000); | |
/* get the pid of the process in which we exec tcpdump | |
* to do that we use the ps command, so we need to launch another process to achieve that | |
*/ | |
Process process2 = Runtime.getRuntime().exec("ps tcpdump-arm"); | |
//read the output of ps | |
DataInputStream in = new DataInputStream(process2.getInputStream()); | |
String temp= in.readLine(); | |
temp = in.readLine(); | |
//We apply a regexp to the second line of the ps output to get the pid | |
temp = temp.replaceAll("^root *([0-9]*).*","$1"); | |
pid = Integer.parseInt(temp); | |
Log.e("MyTemp",""+pid); | |
//the ps process is no more needed | |
process2.destroy(); | |
} | |
catch (Exception e) { | |
// TODO: handle exception | |
} | |
} | |
}; | |
//Init the reader thread | |
readThread=new Thread(){ | |
public void run(){ | |
try { | |
//ensure the file we will read exists | |
boolean fileOK = false; | |
while(!fileOK) { | |
dumpedFile = new File("/data/local/output.txt"); | |
if (dumpedFile.exists()) | |
fileOK = true; | |
} | |
//open a reader on the tcpdump output file | |
reader = new BufferedReader(new FileReader(dumpedFile)); | |
String temp = new String(); | |
//The while loop is broken if the thread is interrupted | |
while (!Thread.interrupted()) { | |
temp = reader.readLine(); | |
if (temp!=null) { | |
Log.e("READER",new String(temp)); | |
buffer.put(new String(temp)); | |
} | |
} | |
} catch (Exception e) { | |
// TODO Auto-generated catch block | |
e.printStackTrace(); | |
} | |
} | |
}; | |
//Init the timer task that display packet in UI | |
displayThread=new TimerTask(){ | |
public void run(){ | |
bufferReader.parse(); | |
} | |
}; | |
} | |
/** | |
* Start the scanning process | |
*/ | |
public void start() { | |
isStarted = true; | |
//launch the tcpdump process | |
tcpdumpTimer = new Timer(); | |
tcpdumpTimer.schedule(tcpdump, 0); | |
//start the reader thread | |
readThread.start(); | |
//Send packet to the UI every 3s | |
displayTimer = new Timer(true); | |
displayTimer.schedule(displayThread, 100, 3000); | |
} | |
/** | |
* Stop the scanning process | |
*/ | |
public void stop() { | |
//stop the display thread | |
displayTimer.cancel(); | |
//stop the reader thread | |
//interrupt the thread will cause the while loop to be break | |
readThread.interrupt(); | |
//close the reader for the tcpdump output file | |
try { reader.close();} catch (IOException e) { e.printStackTrace(); } | |
//stop the tcpdump process | |
tcpdumpTimer.cancel(); | |
process.destroy(); | |
buffer.raz(); | |
//Destroy the tcpdump process doesn't cause the process to be stopped on the system | |
//To achieve that we kill the process | |
try { | |
//to kill tcpdump process we create a new process to run the kill command | |
//this process terminate immediately so we doesn't need to kill it | |
String killCommand = "kill "+pid; | |
Process process2 = Runtime.getRuntime().exec("su"); | |
DataOutputStream os = new DataOutputStream(process2.getOutputStream()); | |
os.writeBytes(killCommand); | |
os.flush(); | |
os.writeBytes("exit\n"); | |
os.flush(); | |
os.close(); | |
} catch (IOException e) { | |
// TODO Auto-generated catch block | |
e.printStackTrace(); | |
} | |
//We also need to delete the output file | |
try { | |
Process process2 = Runtime.getRuntime().exec("su"); | |
DataOutputStream os = new DataOutputStream(process2.getOutputStream()); | |
os.writeBytes("rm /data/local/output.txt\n"); | |
os.flush(); | |
os.writeBytes("exit\n"); | |
os.flush(); | |
os.close(); | |
} catch (IOException e) { | |
// TODO Auto-generated catch block | |
e.printStackTrace(); | |
} | |
//To launch another time the scanning process we need to init threads and timers | |
init(); | |
isStarted=false; | |
} | |
public Buffer getOutput(){ | |
return buffer; | |
} | |
public boolean isStarted(){ | |
return isStarted; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment