5

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));
        }
}
}
Alpay
  • 1,350
  • 2
  • 24
  • 56

3 Answers3

1

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.

CaptainCap
  • 334
  • 2
  • 13
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 {
      ....
 }
Ortomala Lokni
  • 56,620
  • 24
  • 188
  • 240
  • Doesn't appear to be what OP asking for. – user207421 Jul 15 '14 at 22:47
  • OP said: "How can I reconstruct these packets in real-time? I want to reconstruct TCP sessions while listening the network card and capturing new packets." I answer to that. The code, he provided is just a trial. – Ortomala Lokni Jul 16 '14 at 12:39
  • Your answer is about reconstructing *packets.* He is asking about reconstructing *sessions.* – user207421 Jul 17 '14 at 08:51
  • In the first sentence, I've made a mistake and interchanged packet and stream but now it's corrected. The rest of the answer is correct. The method reassemblePacket receives a tcp packet and reconstructs the stream. – Ortomala Lokni Jul 17 '14 at 09:31
1

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".

R.Sicart
  • 671
  • 3
  • 10
  • 1
    fin packets will definitely end conversations that' s right. But what about rst' s? – Alpay Jul 16 '14 at 05:03
  • I think you can still use ACK sequence number from RST packet to associate it to the right tcp stream but I'm not sure. – R.Sicart Jul 16 '14 at 22:11