我正在使用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));
}
}
}
答案 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;。