/*_##########################################################################
_##
_## Copyright (C) 2011-2013 Kaito Yamada
_##
_##########################################################################
*/
package com.github.kaitoy.sneo.network.protocol;
import org.pcap4j.packet.IcmpV4CommonPacket;
import org.pcap4j.packet.IcmpV4DestinationUnreachablePacket;
import org.pcap4j.packet.IcmpV4EchoPacket;
import org.pcap4j.packet.IcmpV4EchoReplyPacket;
import org.pcap4j.packet.IcmpV4TimeExceededPacket;
import org.pcap4j.packet.IpV4Packet;
import org.pcap4j.packet.Packet;
import org.pcap4j.packet.SimpleBuilder;
import org.pcap4j.packet.namednumber.IcmpV4Code;
import org.pcap4j.packet.namednumber.IcmpV4Type;
import com.github.kaitoy.sneo.network.NetworkInterface;
import com.github.kaitoy.sneo.network.Node;
import com.github.kaitoy.sneo.network.SendPacketException;
public final class IcmpV4Helper {
private IcmpV4Helper() { throw new AssertionError(); }
public static void reply(Packet packet, Node node, NetworkInterface nif) {
IcmpV4EchoPacket echo = packet.get(IcmpV4EchoPacket.class);
Packet.Builder outer = packet.getBuilder().getOuterOf(IcmpV4EchoPacket.Builder.class);
IpV4Packet ipv4 = packet.get(IpV4Packet.class);
if (
echo == null
|| ipv4 == null
|| outer == null
|| !(outer instanceof IcmpV4CommonPacket.Builder)
) {
throw new IllegalArgumentException(packet.toString());
}
IcmpV4EchoReplyPacket.Builder repb = new IcmpV4EchoReplyPacket.Builder();
repb.identifier(echo.getHeader().getIdentifier())
.sequenceNumber(echo.getHeader().getSequenceNumber())
.payloadBuilder(new SimpleBuilder(echo.getPayload()));
((IcmpV4CommonPacket.Builder)outer).type(IcmpV4Type.ECHO_REPLY)
.payloadBuilder(repb)
.correctChecksumAtBuild(true);
try {
node.sendL4Packet(
outer.build(),
ipv4.getHeader().getDstAddr(),
ipv4.getHeader().getSrcAddr(),
nif
);
} catch (SendPacketException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
}
public static void sendErrorMessage(
IcmpV4Type type,
IcmpV4Code code,
Packet packet,
Node node,
NetworkInterface nif
) {
IpV4Packet ipv4Packet = packet.get(IpV4Packet.class);
if (ipv4Packet == null) {
throw new IllegalArgumentException(packet.toString());
}
Packet.Builder icmpV4Inet;
if (type.equals(IcmpV4Type.DESTINATION_UNREACHABLE)) {
icmpV4Inet
= new IcmpV4DestinationUnreachablePacket.Builder()
.payload(
org.pcap4j.util.IcmpV4Helper
.makePacketForInvokingPacketField(ipv4Packet)
);
}
else if (type.equals(IcmpV4Type.TIME_EXCEEDED)) {
icmpV4Inet
= new IcmpV4TimeExceededPacket.Builder()
.payload(
org.pcap4j.util.IcmpV4Helper
.makePacketForInvokingPacketField(ipv4Packet)
);
}
else {
throw new IllegalArgumentException(packet.toString());
}
IcmpV4CommonPacket.Builder icmpV4Common = new IcmpV4CommonPacket.Builder();
icmpV4Common.type(type)
.code(code)
.payloadBuilder(icmpV4Inet)
.correctChecksumAtBuild(true);
try {
node.sendL4Packet(
icmpV4Common.build(),
nif.getIpAddresses().get(0).getIpAddr(),
ipv4Packet.getHeader().getSrcAddr(),
nif
);
} catch (SendPacketException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
}
}