5

我正在监听一个特定的网卡并使用 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));
        }
}
}
4

3 回答 3

1

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

/*
* 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 {
      ....
 }
于 2014-07-11T19:53:15.047 回答
1

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

于 2014-07-15T22:32:21.487 回答
1

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

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

于 2014-06-24T13:45:33.123 回答