原文: https://javatutorial.net/capture-network-packages-java

该示例演示了如何使用 pcap 和 Java 捕获网络数据包。

要运行示例,您将需要为操作系统安装 libpcap 。 对于 Windows,下载并安装 WinPcap

Ubuntu 用户可以运行以下命令来安装 libpcap:

  1. sudo apt-get install libpcap-dev

我们将使用 jNetPcap 作为 Java 包装器。 以下示例要求版本 1.4

列出网络设备

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import org.jnetpcap.Pcap;
  4. import org.jnetpcap.PcapIf;
  5. public class NetworkInterfaces {
  6. public static void main(String[] args) {
  7. List<PcapIf> alldevs = new ArrayList<PcapIf>(); // Will be filled with NICs
  8. StringBuilder errbuf = new StringBuilder(); // For any error msgs
  9. int r = Pcap.findAllDevs(alldevs, errbuf);
  10. if (r == Pcap.NOT_OK || alldevs.isEmpty()) {
  11. System.err.printf("Can't read list of devices, error is %s",
  12. errbuf.toString());
  13. return;
  14. }
  15. System.out.println("Network devices found:");
  16. int i = 0;
  17. for (PcapIf device : alldevs) {
  18. String description = (device.getDescription() != null) ? device
  19. .getDescription() : "No description available";
  20. System.out.printf("#%d: %s [%s]\n", i++, device.getName(),
  21. description);
  22. }
  23. }
  24. }

捕捉数据包

以下完整示例捕获了前 10 个数据包:

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import org.jnetpcap.Pcap;
  4. import org.jnetpcap.PcapIf;
  5. import org.jnetpcap.packet.PcapPacket;
  6. import org.jnetpcap.packet.PcapPacketHandler;
  7. import org.jnetpcap.protocol.network.Ip4;
  8. public class PackageCapture {
  9. public static void main(String[] args) {
  10. List<PcapIf> alldevs = new ArrayList<PcapIf>(); // Will be filled with NICs
  11. StringBuilder errbuf = new StringBuilder(); // For any error msgs
  12. int r = Pcap.findAllDevs(alldevs, errbuf);
  13. if (r != Pcap.OK || alldevs.isEmpty()) {
  14. System.err.printf("Can't read list of devices, error is %s",
  15. errbuf.toString());
  16. return;
  17. }
  18. System.out.println("Network devices found:");
  19. int i = 0;
  20. for (PcapIf device : alldevs) {
  21. String description = (device.getDescription() != null) ? device
  22. .getDescription() : "No description available";
  23. System.out.printf("#%d: %s [%s]\n", i++, device.getName(),
  24. description);
  25. }
  26. PcapIf device = alldevs.get(0); // Get first device in list
  27. System.out.printf("\nChoosing '%s' on your behalf:\n",
  28. (device.getDescription() != null) ? device.getDescription()
  29. : device.getName());
  30. int snaplen = 64 * 1024; // Capture all packets, no trucation
  31. int flags = Pcap.MODE_PROMISCUOUS; // capture all packets
  32. int timeout = 10 * 1000; // 10 seconds in millis
  33. Pcap pcap = Pcap.openLive(device.getName(), snaplen, flags, timeout, errbuf);
  34. if (pcap == null) {
  35. System.err.printf("Error while opening device for capture: "
  36. + errbuf.toString());
  37. return;
  38. }
  39. PcapPacketHandler<String> jpacketHandler = new PcapPacketHandler<String>() {
  40. public void nextPacket(PcapPacket packet, String user) {
  41. byte[] data = packet.getByteArray(0, packet.size()); // the package data
  42. byte[] sIP = new byte[4];
  43. byte[] dIP = new byte[4];
  44. Ip4 ip = new Ip4();
  45. if (packet.hasHeader(ip) == false) {
  46. return; // Not IP packet
  47. }
  48. ip.source(sIP);
  49. ip.destination(dIP);
  50. /* Use jNetPcap format utilities */
  51. String sourceIP = org.jnetpcap.packet.format.FormatUtils.ip(sIP);
  52. String destinationIP = org.jnetpcap.packet.format.FormatUtils.ip(dIP);
  53. System.out.println("srcIP=" + sourceIP +
  54. " dstIP=" + destinationIP +
  55. " caplen=" + packet.getCaptureHeader().caplen());
  56. }
  57. };
  58. // capture first 10 packages
  59. pcap.loop(10, jpacketHandler, "jNetPcap");
  60. pcap.close();
  61. }
  62. }

如果要捕获特定的数据包,可以设置一个过滤器,如下所示:

  1. PcapBpfProgram filter = new PcapBpfProgram();
  2. String expression = "tcp port 3724 or tcp port 1119";
  3. int optimize = 0; // 0 = false
  4. int netmask = 0xFFFFFF00; // 255.255.255.0
  5. if (pcap.compile(filter, expression, optimize, netmask) != Pcap.OK) {
  6. System.err.println(pcap.getErr());
  7. return;
  8. }
  9. if (pcap.setFilter(filter) != Pcap.OK) {
  10. System.err.println(pcap.getErr());
  11. return;
  12. }