【问题标题】:Real-Time TCP session reconstruction in Java using jPcap使用 jPcap 在 Java 中实时重建 TCP 会话
【发布时间】:2014-06-24 12:07:44
【问题描述】:

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

在Wireshark中,我可以选择“follow tcp stream”,这样我就可以从头到尾得到整个会话。我想在 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));
        }
}
}

【问题讨论】:

    标签: java networking tcp jpcap


    【解决方案1】:

    我对 jPcap 了解不多(我记得在某处读过 - here 你应该使用 jNetPcap)但我会根据存储会话使用HashMap&lt;String,TCPPacket&gt; tcp 会话,String 键例如String.join('.',remotehost_tcp_address,remote_host_tcp_port),然后等待 RST 或 FIN-FIN+ACK-ACK 序列将其删除。

    请注意,如果您的系统遇到繁重的网络负载,这可能是一项代价高昂的操作,并且您可能还想注意超时的对话。

    【讨论】:

    • 至少有三个不同的项目叫做 jPcap,质量参差不齐。
    【解决方案2】:

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

    【讨论】:

    • fin 数据包肯定会结束对话,这是正确的。但是 rst 呢?
    • 我认为您仍然可以使用 RST 数据包中的 ACK 序列号将其关联到正确的 tcp 流,但我不确定。
    【解决方案3】:

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

    【讨论】:

    • 似乎不是 OP 要求的。
    • OP 说:“如何实时重建这些数据包?我想在监听网卡并捕获新数据包的同时重建 TCP 会话。”我对此作出回答。他提供的代码只是一个试用版。
    • 你的答案是关于重构数据包。他在问关于重构会话。
    • 在第一句话中,我犯了一个错误并交换了数据包和流,但现在它已得到纠正。其余的答案是正确的。 reassemblePacket 方法接收一个 tcp 数据包并重构流。
    猜你喜欢
    • 2011-12-19
    • 1970-01-01
    • 2020-11-29
    • 2012-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多