使用jPcap在Java中进行实时TCP会话重建

时间:2014-06-24 12:07:44

标签: java networking tcp jpcap

我正在使用jPcap库监听特定的网卡并捕获TCP(仅TCP)数据包。但是,我需要有整个TCP会话,而不是单个数据包。

在Wireshark中,我可以选择“关注tcp流”,这样我就可以从头到尾完成整个对话。我想在Java中做到这一点。如何实时重建这些数据包?我想在侦听网卡和捕获新数据包的同时重建TCP会话。我怎样才能做到这一点?这是我捕获数据包的代码:

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));
        }
}
}

3 个答案:

答案 0 :(得分:1)

我不太了解jPcap(我记得在某处读过 - here你宁愿使用jNetPcap)但是我会根据存储对话使用HashMap<String,TCPPacket> tcp对话, String密钥为例如String.join('.',remotehost_tcp_address,remote_host_tcp_port),然后等待RST或FIN-FIN + ACK-ACK序列将其删除。

请注意,如果您的系统遇到大量网络负载,并且您可能还想观看超时对话,则可能会进行成本高昂的操作。

答案 1 :(得分:1)

pcap-reconst项目提供了一个从pcap文件重建TCP流的框架。您可以使用类TcpReassembler的方法public void reassemblePacket(TcpPacket tcpPacket)来完成这项工作。

/*
* 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 {
      ....
 }

答案 2 :(得分:1)

您可以尝试按源主机,源端口,目标主机,目标端口和连续序列号对数据包进行分组。要知道会话何时开始,您可以检查SYN设置为1的数据包,此时您可以捕获ISN(初始序列号),所有后来ISN + 1..ISN + n的数据包将在同一个tcp流中。要知道会话何时结束,您必须检查FIN数据包。 维基百科的链接不错http://en.m.wikipedia.org/wiki/Transmission_Control_Protocol但是为了更好和更深入的阅读,我推荐你&#34; TCP / IP Illustrated vol.1&#34;。