package com.aionemu.packetsamurai;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
import java.util.concurrent.CountDownLatch;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javolution.util.FastList;
import javolution.util.FastSet;
import jpcap.JpcapCaptor;
import jpcap.NetworkInterfaceAddress;
import jpcap.packet.IPPacket;
import jpcap.packet.Packet;
import org.xbill.DNS.DClass;
import org.xbill.DNS.ExtendedResolver;
import org.xbill.DNS.Message;
import org.xbill.DNS.Name;
import org.xbill.DNS.Record;
import org.xbill.DNS.Resolver;
import org.xbill.DNS.ReverseMap;
import org.xbill.DNS.Section;
import org.xbill.DNS.Type;
import com.aionemu.packetsamurai.gui.Main;
import com.aionemu.packetsamurai.protocol.ProtocolManager;
import com.aionemu.packetsamurai.session.TCPSession;
/**
*
* @author Gilles Duboscq
*
*/
public class FileCaptor extends Captor
{
private Set<TCPSession> _fileCaptorSessions;
public FileCaptor(String pcapFile)
{
_fileCaptorSessions = new FastSet<TCPSession>();
try
{
_packetCaptor = JpcapCaptor.openFile(pcapFile);
Set<Integer> ports = ProtocolManager.getInstance().getAvailablePorts();
Iterator<Integer> i = ports.iterator();
StringBuilder portsSB = new StringBuilder();
if(i.hasNext())
{
StringBuilder sb = new StringBuilder("tcp port");
for(; i.hasNext();)
{
Integer port = i.next();
sb.append(" "+port);
portsSB.append(port);
if(i.hasNext())
{
sb.append(" or tcp port");
portsSB.append(" ");
}
}
_packetCaptor.setFilter(sb.toString(),true);
}
setCaptor(true);
PacketSamurai.getUserInterface().log("Successfully opened File "+pcapFile+".");
PacketSamurai.getUserInterface().log("Filtering for port(s): "+portsSB);
}
catch (IOException ioe)
{
PacketSamurai.getUserInterface().log("ERROR: Failed to open file ("+pcapFile+") for capture"+ioe);
}
}
public void proccesCaptureFile()
{
// TODO move this dialog stuff from here or at least redo the threading stuff correctly
final JDialog dialog = new JDialog(((Main) PacketSamurai.getUserInterface()).getMainFrame(),"Please Wait");
JPanel panel = new JPanel();
dialog.setContentPane(panel);
panel.add(new JLabel("Please wait, Getting TCP packets and resolving host names..."));
dialog.setSize(400, 75);
dialog.setResizable(false);
dialog.setLocationRelativeTo(((Main) PacketSamurai.getUserInterface()).getMainFrame());
dialog.setVisible(true);
final CountDownLatch mainlatch = new CountDownLatch(1);
Thread pthread = new Thread(new Runnable()
{
public void run()
{
final FastList<Packet> packets = new FastList<Packet>();
Vector<InetAddress> addresses = new Vector<InetAddress>();
Set<InetAddress> ipAddresses = new FastSet<InetAddress>(); // just used for teh contains() call
while (true)
{
Packet p = _packetCaptor.getPacket();
if (p == null || p == Packet.EOF)
{
break;
}
packets.add(p);
InetAddress addr = ((IPPacket)p).src_ip;
if(!addresses.contains(addr))
{
try
{
Resolver res = new ExtendedResolver();
Name name = ReverseMap.fromAddress(addr.getAddress());
int type = Type.PTR;
int dclass = DClass.IN;
Record rec = Record.newRecord(name, type, dclass);
Message query = Message.newQuery(rec);
Message response = res.send(query);
Record[] answers = response.getSectionArray(Section.ANSWER);
if (answers.length > 0)
addr = InetAddress.getByAddress(answers[0].rdataToString(), addr.getAddress());
} catch (UnknownHostException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
addresses.add(addr);
}
ipAddresses.add(((IPPacket)p).src_ip);
}
System.err.println("asd");
final CountDownLatch latch = new CountDownLatch(1);
final JDialog choseDialog = new JDialog(((Main) PacketSamurai.getUserInterface()).getMainFrame(),"Chose client inet address");
JPanel chosePanel = new JPanel();
JButton okButton = new JButton("Ok");
okButton.setActionCommand("ok");
final JComboBox combo = new JComboBox(addresses);
okButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent a)
{
if(a.getActionCommand().equals("ok"))
{
_networkAddress = new NetworkInterfaceAddress[1];
_networkAddress[0] = new NetworkInterfaceAddress(null, null, null, null);
_networkAddress[0].address = (InetAddress) combo.getSelectedItem();
choseDialog.setVisible(false);
choseDialog.dispose();
latch.countDown();
}
}
});
JLabel lbl = new JLabel("Please choose the client IP InetAddress");
chosePanel.add(lbl);
chosePanel.add(combo);
chosePanel.add(okButton);
choseDialog.setSize(450, 150);
choseDialog.setResizable(false);
choseDialog.setContentPane(chosePanel);
choseDialog.setLocationRelativeTo(((Main) PacketSamurai.getUserInterface()).getMainFrame());
dialog.setVisible(false);
choseDialog.setVisible(true);
Thread t = new Thread
(
new Runnable()
{
public void run()
{
try
{
latch.await();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
System.err.println("We have "+packets.size()+" tcp packets");
if(_networkAddress != null)
{
for(Packet p : packets)
{
((PacketHandler) _packetHandler).processReceivedPacket(p);
}
}
else
{
System.err.println("Null network address");
}
_packetCaptor.close();
mainlatch.countDown();
}
}
);
t.start();
try
{
t.join();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
pthread.start();
try
{
pthread.join();
}
catch (InterruptedException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
try
{
mainlatch.await();
dialog.dispose();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* @return A TCPSession if this is a file captor, null otherwise
*/
public Set<TCPSession> getFileTCPSessions()
{
return _fileCaptorSessions;
}
public void run()
{
throw new IllegalStateException("Can not call run on a FileCaptor");
}
public TCPSession getSessionByID(long sessionId)
{
for(TCPSession s : _fileCaptorSessions)
{
if(s.getSessionId() == sessionId)
return s;
}
return null;
}
public void addFileTCPSession(TCPSession tcpSession)
{
System.err.println("ADICIONEI SESSION");
System.err.flush();
_fileCaptorSessions.add(tcpSession);
}
}