I am listening a specific network card and capturing TCP(just TCP) packets using jPcap library. However, I need to have whole TCP sessions, not individual packets.
In Wireshark, I can choose "follow tcp stream", so that I can get the whole conversation from beginning to end. I want to do exactly that in Java. How can I reconstruct these packets in real-time? I want to reconstruct TCP sessions while listening the network card and capturing new packets. How can I achieve this? Here is my code to capture packets:
jpcap.NetworkInterface[] devices = JpcapCaptor.getDeviceList();
JpcapCaptor captor = JpcapCaptor.openDevice(devices[1], 65535, true, 1000);
JpcapWriter writer = JpcapWriter.openDumpFile(captor, "myNetworkDump");
captor.loopPacket(-1, new PacketPrinter(writer));
class PacketPrinter implements PacketReceiver {
private HashMap<Long, ArrayList<Packet>> sessions;
private BufferedWriter out;
private JpcapWriter writer;
Map<Long, TCPBodyData> bodies = new HashMap<Long, TCPBodyData>();
public PacketPrinter(JpcapWriter writer) {
this.writer = writer;
this.sessions = new HashMap<Long, ArrayList<Packet>>();
}
public void receivePacket(Packet packet) {
System.out.println(packet);
if (packet instanceof TCPPacket) {
TCPPacket tcppacl = (TCPPacket) packet;
byte[] body = addBodyData(tcppacl);
// System.out.println(new String(body));
}
}
}
I don't know much about jPcap (and I remember reading somewhere - here that you should rather use jNetPcap) but I would use a HashMap<String,TCPPacket>
the tcp conversation according to store the conversation, the String
key being for instance String.join('.',remotehost_tcp_address,remote_host_tcp_port)
, then wait for a RST or FIN-FIN+ACK-ACK sequence to remove it.
Note that it might be a costly operation if your system experience a heavy network load, and you also might want to watch for timed out conversations.
You could try to group packets by source host, source port, destination host, destination port and consecutives sequence numbers. To know when a session begins you can check packets with SYN set to 1, at this moment you can capture the ISN (Initial Sequence Number) and all later packets with ISN+1..ISN+n will be in the same tcp stream. To know when a session ends you have to check for a FIN packet. Wikipedia's link is not bad http://en.m.wikipedia.org/wiki/Transmission_Control_Protocol but for better and deep reading I recommend you "TCP/IP Illustrated vol.1".
The pcap-reconst project provides a framework for reconstructing TCP stream from pcap files. You can use the method public void reassemblePacket(TcpPacket tcpPacket)
of the class TcpReassembler
to do the job.
/*
* The main function of the class receives a tcp packet and reconstructs the stream
*/
public void reassemblePacket(TcpPacket tcpPacket) throws Exception {
....
}
/*
*Get the TCP stream
*/
public OutputStream getOutputStream() {
return outputStream;
}
/*
* Reconstructs the tcp session
* @param sequence Sequence number of the tcp packet
* @param length The size of the original packet data
* @param data The captured data
* @param data_length The length of the captured data
* @param synflag
* @param net_src The source ip address
* @param net_dst The destination ip address
* @param srcport The source port
* @param dstport The destination port
*/
private void reassembleTcp(long sequence, long ack_num, long length, byte[] data,
int dataLength, boolean synflag,
TcpConnection tcpConnection) throws Exception {
....
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With