我想实现基本的网络检查功能,以测试所提供的网址是否响应(例如。ping www.google.com).It必须提供操作信息,例如,指示请求的服务不可用或无法到达主机。我能够使用icmp4j库实现它。但是我想使用pcap4j库来实现同样的目标。我想把网址放在文本框中,然后点击连接按钮,这将调用pcap4j api来检查主机是否响应。
发布于 2016-11-19 21:55:06
您可以使用IcmpV4EchoPacket、IcmpV4CommonPacket、IpV4Packet和EthernetPacket的构建器在以太网数据包上创建Echo (ping),并通过PcapHandle.sendPacket()发送它们。请参阅pcap4j样例项目中的org.pcap4j.sample.SendFragmentedEcho。
您需要实现ARP来将IP地址解析为pcap4j示例项目中的org.pcap4j.sample.SendArpRequest等MAC地址。
您还需要实现一个功能,以便从给定的IP地址找到下一个跳(默认网关)。Pcap4J不提供支持此实现的API。(Java不提供API来获取路由表.)
你最好用java.net.InetAddress#isReachable()代替。
发布于 2022-02-04 11:54:28
我花了一年多的时间才弄明白这一点,因为我想用pcap4j制作一个traceroute,下面是我所做的:
PcapNetworkInterface轻松实现。IcmpV4EchoPacket并发送IcmpV4EchoReplyPacket,它可能是对您的请求的回答(请检查标识符和序列号以确保)IcmpV4TimeExceededPacket。需要填写的变量:
short IDENTIFIER; // identifer may be any 16 bit interger
short SEQUENCE; // sequence may be any 16 bit integer
byte TTL; // time to live (1-255)
Inet4Address IP_TARGET; // ip address of your ping target
Inet4Address IP_ORIGIN; // your own ip address
MacAddress MAC_TARGET; // target or gateway mac address
MacAddress MAC_SOURCE; // your own mac address
PcapNetworkInterface PCAP4J_NETWORK_INTERFACE; // network interface used to execute the ping如何制作ICMP回波请求包(作为IcmpV4CommonPacket of IpV4Packet of EthernetPacket的有效负载):
public Packet buildPacket() {
IcmpV4EchoPacket.Builder icmpV4Echo = new IcmpV4EchoPacket.Builder()
.identifier(IDENTIFIER) // optional, default zero
.sequenceNumber(SEQUENCE); // optional, default zero
IcmpV4CommonPacket.Builder icmpV4Common = new IcmpV4CommonPacket.Builder()
.type(IcmpV4Type.ECHO) // type is echo
.code(IcmpV4Code.NO_CODE) // echo request doesn't need this
.payloadBuilder(icmpV4Echo)
.correctChecksumAtBuild(true);
IpV4Packet.Builder ipv4Builder = new IpV4Packet.Builder()
.correctChecksumAtBuild(true)
.correctLengthAtBuild(true)
.dstAddr(IP_TARGET) // IPv4 Address where tp send the request
.payloadBuilder(icmpV4Common)
.protocol(IpNumber.ICMPV4) // payload is ICMPV4
.srcAddr(IP_ORIGIN) // Your own IPv4 Address
.tos(IpV4Rfc1349Tos.newInstance((byte) 0))
.ttl(TTL) // time to live (1-255)
.version(IpVersion.IPV4); // IP Version is IPv4
EthernetPacket.Builder etherBuilder = new EthernetPacket.Builder()
.dstAddr(MAC_TARGET) // the targets mac address
.srcAddr(MAC_SOURCE) // your own mac address
.type(EtherType.IPV4) // payload protocl is IPv4
.payloadBuilder(ipv4Builder)
.paddingAtBuild(true);
return etherBuilder.build(); // build your packet
}ICMP回声应答或超时的侦听器:
public PacketListener buildListener() {
return new PacketListener() {
@Override
public void gotPacket(Packet packet) {
if (!(packet instanceof EthernetPacket))
return;
EthernetPacket ethernetPacket = (EthernetPacket) packet;
packet = ethernetPacket.getPayload();
if (!(packet instanceof IpV4Packet))
return;
IpV4Packet ipV4Packet = (IpV4Packet) packet;
IpV4Header ipV4Header = ipV4Packet.getHeader();
packet = ipV4Packet.getPayload();
if (!(packet instanceof IcmpV4CommonPacket))
return;
IcmpV4CommonPacket icmpPacket = (IcmpV4CommonPacket) packet;
packet = icmpPacket.getPayload();
// successful reply just measure time and done
if (packet instanceof IcmpV4EchoReplyPacket) {
IcmpV4EchoReplyPacket icmpV4EchoReplyPacket = (IcmpV4EchoReplyPacket) packet;
IcmpV4EchoReplyHeader icmpV4EchoReplyHeader = icmpV4EchoReplyPacket.getHeader();
if (icmpV4EchoReplyHeader.getIdentifier() != identifier)
return;
if (icmpV4EchoReplyHeader.getSequenceNumber() != sequence)
return;
// here you got an echo reply
System.out.println(packet);
return;
}
// try handle time to live exceeded messages
if (packet instanceof IcmpV4TimeExceededPacket) {
packet = packet.getPayload(); // original IPv4
if (!(packet instanceof IpV4Packet))
return;
packet = packet.getPayload(); // original ICMP common
if (!(packet instanceof IcmpV4CommonPacket))
return;
packet = packet.getPayload(); // original ICMP echo
if (!(packet instanceof IcmpV4EchoPacket))
return;
IcmpV4EchoHeader icmpV4EchoHeader = ((IcmpV4EchoPacket)packet).getHeader();
if (icmpV4EchoHeader.getIdentifier() != IDENTIFIER)
return;
if(icmpV4EchoHeader.getSequenceNumber() != SEQUENCE)
return;
// HERE you got an answer, that the time to live has been used up
System.out.println(packet);
return;
}
};
}把它结合起来:
public static void main(String[] args) throws IOException, PcapNativeException, NotOpenException, InterruptedException {
try (PcapHandle handle = PCAP4J_NETWORK_INTERFACE.openLive(1024, PromiscuousMode.PROMISCUOUS, 1000)) {
// set filter to only get incoming ICMP traffic
handle.setFilter("icmp and dst host " + Pcaps.toBpfString(IP_ORIGIN), BpfCompileMode.OPTIMIZE);
// send ARP request
Packet p = buildPacket();
handle.sendPacket(p);
// wait (forever) for ARP answer
PacketListener listener = buildListener();
handle.loop(-1, listener);
}
}https://stackoverflow.com/questions/40629657
复制相似问题