package org.kne.cloud.network.ipv6; import java.io.IOException; import java.nio.ByteBuffer; import org.kne.cloud.network.NetworkPacket; import org.kne.io.KNEChannels; public class ICMPv6TimeExceededPacket extends ICMPv6Packet { private static final int UNUSED_FIELD_LENGTH = 4; // 未使用字段长度 // 代码值常量 public static final int CODE_HOP_LIMIT_EXCEEDED = 0; // 跳数限制超时 public static final int CODE_FRAGMENT_REASSEMBLY_EXCEEDED = 1; // 分片重组超时 public ICMPv6TimeExceededPacket(int code) { super(TYPE_TIME_EXCEEDED, code); setUnused(0); } /** * 获取未使用字段(通常为0) */ public int getUnused() { return getHeader().getInt(4); } /** * 设置未使用字段(通常设为0) */ public void setUnused(int unused) { getHeader().putInt(4, unused); } /** * 创建跳数限制超时包 */ public static ICMPv6TimeExceededPacket createHopLimitExceeded(IPv6Packet originalPacket) { ICMPv6TimeExceededPacket packet = new ICMPv6TimeExceededPacket(CODE_HOP_LIMIT_EXCEEDED); // 包含原始数据包的前缀(根据RFC,尽可能包含但不超出最小MTU) if (originalPacket == null) { throw new NullPointerException("originalPacket is null!"); } // 这里简化处理,实际应该序列化原始包的前1280字节(IPv6最小MTU) ByteBuffer buffer = NetworkPacket.bufferAllocator.allocate(65536); buffer.clear(); try { originalPacket.writeToChannel(KNEChannels.newWritableChannel(buffer)); } catch (IOException e) { e.printStackTrace(); } buffer.flip(); buffer.limit(Math.min(1280, buffer.limit())); packet.getData().clear(); packet.getData().put(buffer); packet.getData().flip(); return packet; } @Override public String toString() { String codeStr = getCode() == CODE_HOP_LIMIT_EXCEEDED ? "Hop Limit Exceeded" : "Fragment Reassembly Time Exceeded"; return String.format("ICMPv6 Time Exceeded [%s, OriginalPrefix:%d bytes]", codeStr, getDataLength()); } }