Skip to content

Instantly share code, notes, and snippets.

Created December 15, 2012 05:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anonymous/4291527 to your computer and use it in GitHub Desktop.
Save anonymous/4291527 to your computer and use it in GitHub Desktop.
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