package org.kne.cloud.network.ipv6; import java.io.EOFException; import java.io.IOException; import java.io.StreamCorruptedException; import java.net.Inet6Address; import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; import java.util.ArrayList; import java.util.List; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import org.kne.cloud.network.NetworkPacket; import org.kne.cloud.network.klalb.KLALBPacket; import org.kne.cloud.network.kltp.KLTPPacket; import org.kne.cloud.network.srv6.IPv6SegmentRoutingTLV; import org.kne.cloud.network.tcp.UDPPacket; import org.kne.io.KNEChannels; /** * IPv6数据包类,继承自NetworkPacket,用于处理IPv6网络数据包 */ public class IPv6Packet extends NetworkPacket { private static final boolean debug=false; // ==================== IPv6扩展头类型 ==================== /** 逐跳选项头 - RFC 8200 */ public static final int HOP_BY_HOP_OPTIONS = 0; /** ICMPv4 - RFC 792 */ public static final int ICMPv4 = 1; /** IGMP - RFC 1112 */ public static final int IGMP = 2; /** IPv4封装 - RFC 2003 */ public static final int IPv4 = 4; /** TCP - RFC 793 */ public static final int TCP = 6; /** EGP - RFC 888 */ public static final int EGP = 8; /** IGP - RFC 891 */ public static final int IGP = 9; /** UDP - RFC 768 */ public static final int UDP = 17; /** IPv6封装 - RFC 2473 */ public static final int IPv6 = 41; /** 路由头 - RFC 8200 */ public static final int ROUTING = 43; /** 分片头 - RFC 8200 */ public static final int FRAGMENT = 44; /** RSVP - RFC 2205 */ public static final int RSVP = 46; /** GRE - RFC 2784 */ public static final int GRE = 47; /** 封装安全载荷 - RFC 4303 */ public static final int ESP = 50; /** 认证头 - RFC 4302 */ public static final int AH = 51; /** ICMPv6 - RFC 4443 */ public static final int ICMPv6 = 58; /** 无下一个头 - RFC 8200 */ public static final int NO_NEXT_HEADER = 59; /** 目的选项头 - RFC 8200 */ public static final int DESTINATION_OPTIONS = 60; /** 移动IPv6 - RFC 6275 */ public static final int MOBILITY = 135; /** Shim6 - RFC 5533 */ public static final int SHIM6 = 140; /** 实验性和测试用途 - RFC 3692 */ public static final int EXPERIMENTAL_1 = 253; /** 实验性和测试用途 - RFC 3692 */ public static final int EXPERIMENTAL_2 = 254; /** 保留 - RFC 8200 */ public static final int RESERVED = 255; // ==================== 上层协议类型 ==================== /** OSPF - RFC 2328 */ public static final int OSPF = 89; /** SCTP - RFC 4960 */ public static final int SCTP = 132; /** MPLS in IP - RFC 4023 */ public static final int MPLS_IN_IP = 137; /** MANET协议 - RFC 5498 */ public static final int MANET = 138; // ==================== 特殊用途 ==================== /** IPv6选项 - RFC 8200 */ public static final int IPv6_OPTIONS = 0; /** 主机身份协议HIP(HOST_IDENTITY_PROTOCOL) - RFC 5201 */ public static final int HIP = 139; /** 无线接入网协议 - RFC 5845 */ public static final int WARP = 142; // ==================== SRv6相关常量 ==================== /** SRv6路由类型 */ public static final int SRV6_ROUTING_TYPE = 4; // ==================== 地址相关常量 ==================== /** IPv6地址长度(字节) */ public static final int IPV6_ADDRESS_LENGTH = 16; /** IPv6地址长整型部分数量 */ public static final int IPV6_ADDRESS_LONGS = 2; // ==================== 位操作相关常量 ==================== public static final int BIT_MASK_LOW_4_BITS = 0b00001111; public static final int BIT_MASK_HIGH_4_BITS = 0b11110000; public static final int BIT_MASK_LOW_8_BITS = 0xFF; public static final int BIT_MASK_LOW_16_BITS = 0xFFFF; public static final int BIT_MASK_LOW_32_BITS = 0xFFFFFFFF; // ==================== 扩展头对齐常量 ==================== public static final int EXT_HEADER_ALIGNMENT = 8; // ==================== 工具方法 ==================== /** * 获取Next Header的名称 */ public static String getName(int nextHeader) { switch (nextHeader) { case HOP_BY_HOP_OPTIONS: return "Hop-by-Hop Options"; case ICMPv4: return "ICMPv4"; case IGMP: return "IGMP"; case IPv4: return "IPv4"; case TCP: return "TCP"; case EGP: return "EGP"; case IGP: return "IGP"; case UDP: return "UDP"; case IPv6: return "IPv6"; case ROUTING: return "Routing Header"; case FRAGMENT: return "Fragment Header"; case RSVP: return "RSVP"; case GRE: return "GRE"; case ESP: return "Encapsulating Security Payload"; case AH: return "Authentication Header"; case ICMPv6: return "ICMPv6"; case NO_NEXT_HEADER: return "No Next Header"; case DESTINATION_OPTIONS: return "Destination Options"; case MOBILITY: return "Mobility Header"; case HIP: return "Host Identity Protocol"; case SHIM6: return "Shim6 Protocol"; case EXPERIMENTAL_1: return "Experimental #1"; case EXPERIMENTAL_2: return "Experimental #2"; case RESERVED: return "Reserved"; case OSPF: return "OSPF"; case SCTP: return "SCTP"; case MPLS_IN_IP: return "MPLS in IP"; case MANET: return "MANET Protocols"; case WARP: return "WARP"; default: return "Unknown (" + nextHeader + ")"; } } /** * 检查是否为IPv6扩展头 */ public static boolean isExtensionHeader(int nextHeader) { return nextHeader == HOP_BY_HOP_OPTIONS || nextHeader == ROUTING || nextHeader == FRAGMENT || nextHeader == DESTINATION_OPTIONS || nextHeader == MOBILITY || nextHeader == HIP || nextHeader == SHIM6; } /** * 检查是否为传输层协议 */ public static boolean isTransportProtocol(int nextHeader) { return nextHeader == TCP || nextHeader == UDP || nextHeader == SCTP; } /** * 检查是否为网络层协议 */ public static boolean isNetworkProtocol(int nextHeader) { return nextHeader == IPv4 || nextHeader == IPv6 || nextHeader == ICMPv4 || nextHeader == ICMPv6; } // TTL是否已减少的标志 private boolean TTLdecreased = false; public boolean isTTLdecreased() { return TTLdecreased; } public void setTTLdecreased(boolean tTLdecreased) { TTLdecreased = tTLdecreased; } // IPv6头部数据缓冲区 private ByteBuffer IPv6header; private IPv6HopByHopHeader hopByHopHeader; private IPv6RoutingHeader routingHeader; // IPv6扩展头部列表 private List headers = new ArrayList<>(); // IPv6负载数据 private IPv6Payload payload; // IPv6头部固定长度 public static final int IPv6_HEADER_LENGTH = 40; // IPv6地址在头部中的偏移量 private static final int SOURCE_ADDRESS_OFFSET = 8; private static final int DESTINATION_ADDRESS_OFFSET = 24; public IPv6Payload getPayload() { return payload; } public void setPayload(IPv6Payload payload) { this.payload = payload; } /** * 默认构造函数,初始化IPv6头部缓冲区 */ public IPv6Packet() { IPv6header = NetworkPacket.bufferAllocator.allocate(IPv6_HEADER_LENGTH); } /** * 从字节中提取IP版本号 * @param b 字节数据 * @return IP版本号 */ public static int getIPVersion(byte b) { return b >>> 4; } /** * 获取IPv6版本号 * @return 版本号 */ public int getVersion() { return IPv6header.get(0) >>> 4; } /** * 设置IPv6版本号 * @param version 版本号 */ public void setVersion(int version) { IPv6header.put(0, (byte) (IPv6header.get(0) & BIT_MASK_LOW_4_BITS | version << 4)); } /** * 获取流量类别 * @return 流量类别 */ public int getTrafficClass() { // 读取字节 0 和字节 1 组成一个 short(16 位) short firstTwoBytes = IPv6header.getShort(0); // 提取 Traffic Class:高 4 位(Version)去掉,剩下就是 8 位 Traffic Class return (firstTwoBytes & 0x0FF0) >>> 4; } /** * 设置流量类别 * @param trafficClass 流量类别 */ public void setTrafficClass(int trafficClass) { // 读取当前的两个字节 short firstTwoBytes = IPv6header.getShort(0); // 清除原来的 Traffic Class 位(将中间 8 位清零) short cleared = (short) (firstTwoBytes & 0xF00F); // 保留高 4 位和低 4 位 // 组合新的 Traffic Class short newValue = (short) (cleared | ((trafficClass & 0xFF) << 4)); // 一次性写回 IPv6header.putShort(0, newValue); } /** * 检查是否启用ECN(显式拥塞通知) * @return 是否启用ECN */ public boolean isEnableECN() { return (IPv6header.get(1) & 0b00110000) != 0; } /** * 启用ECN(显式拥塞通知) */ public void enableECN() { IPv6header.put(1, (byte) ((IPv6header.get(1) & 0b11101111) | 0b00100000)); } /** * 标记CE(拥塞经历) */ public void markCE() { byte g=IPv6header.get(1); if((g& 0b00110000) != 0) { // 启用ECN IPv6header.put(1, (byte) ( g| 0b00110000)); } // new Exception().printStackTrace(); } /** * 检查是否标记了CE(拥塞经历) * @return 是否标记了CE */ public boolean isCE() { return ((IPv6header.get(1) >>> 4) & 0b11) == 0b11; } /** * 获取流标签 * @return 流标签 */ public int getFlowLabel() { // 读取前 4 个字节(32 位) int firstWord = IPv6header.getInt(0); // 提取 Flow Label:高 12 位(Version + Traffic Class)去掉,剩下低 20 位 return firstWord & 0x000FFFFF; } /** * 设置流标签 * @param flowLabel 流标签 */ public void setFlowLabel(int flowLabel) { // 读取当前前 4 个字节 int firstWord = IPv6header.getInt(0); // 清除原来的 Flow Label(将低 20 位清零) int cleared = firstWord & 0xFFF00000; // 保留高 12 位 // 组合新的 Flow Label(只取低 20 位) int newWord = cleared | (flowLabel & 0x000FFFFF); // 一次性写回 IPv6header.putInt(0, newWord); } /** * 获取负载长度 * @return 负载长度 */ public int getPayloadLength() { return IPv6header.getShort(4) & BIT_MASK_LOW_16_BITS; } /** * 设置负载长度 * @param payloadLength 负载长度 */ public void setPayloadLength(int payloadLength) { IPv6header.putShort(4, (short) payloadLength); } /** * 获取下一个头部协议类型 * @return 下一个头部协议类型 */ public int getNextHeader() { return IPv6header.get(6) & BIT_MASK_LOW_8_BITS; } /** * 设置下一个头部协议类型 * @param nextHeader 下一个头部协议类型 */ public void setNextHeader(int nextHeader) { IPv6header.put(6, (byte) nextHeader); } /** * 获取跳数限制 * @return 跳数限制 */ public int getHopLimit() { return IPv6header.get(7) & BIT_MASK_LOW_8_BITS; } /** * 设置跳数限制 * @param hopLimit 跳数限制 */ public void setHopLimit(int hopLimit) { IPv6header.put(7, (byte) hopLimit); } /** * 获取原始源地址字节数组 * @param sourceAddress 用于存储源地址的字节数组 */ public void getRawSourceAddressArray(byte[] sourceAddress) { IPv6header.get(SOURCE_ADDRESS_OFFSET, sourceAddress, 0, sourceAddress.length); } /** * 设置原始源地址字节数组 * @param sourceAddress 源地址字节数组 */ public void setRawSourceAddressArray(byte[] sourceAddress) { IPv6header.put(SOURCE_ADDRESS_OFFSET, sourceAddress, 0, sourceAddress.length); } /** * 获取原始目标地址字节数组 * @param destinationAddress 用于存储目标地址的字节数组 */ public void getRawDestinationAddressArray(byte[] destinationAddress) { IPv6header.get(DESTINATION_ADDRESS_OFFSET, destinationAddress, 0, destinationAddress.length); } /** * 设置原始目标地址字节数组 * @param destinationAddress 目标地址字节数组 */ public void setRawDestinationAddressArray(byte[] destinationAddress) { IPv6header.put(DESTINATION_ADDRESS_OFFSET, destinationAddress, 0, destinationAddress.length); } /** * 获取原始源地址字节数组 * @return */ public IPv6Address getSourceAddress() { return IPv6Address.valueOf(SOURCE_ADDRESS_OFFSET,IPv6header); } /** * 设置原始源地址字节数组 * @param sourceAddress 源地址字节数组 */ public void setSourceAddress(IPv6Address sourceAddress) { sourceAddress.writeTo(SOURCE_ADDRESS_OFFSET,IPv6header); } /** * 获取原始目标地址字节数组 */ public IPv6Address getDestinationAddress() { return IPv6Address.valueOf(DESTINATION_ADDRESS_OFFSET,IPv6header); } /** * 设置原始目标地址字节数组 * @param destinationAddress 目标地址字节数组 */ public void setDestinationAddress(IPv6Address destinationAddress) { destinationAddress.writeTo(DESTINATION_ADDRESS_OFFSET,IPv6header); } /** * 获取源地址 * @return 源地址 */ public Inet6Address getSourceAddress2() { byte[] b = new byte[IPV6_ADDRESS_LENGTH]; IPv6header.get(SOURCE_ADDRESS_OFFSET, b, 0, b.length); try { return (Inet6Address) Inet6Address.getByAddress(b); } catch (UnknownHostException e) { return null; } } /** * 设置源地址 * @param sourceAddress 源地址 */ public void setSourceAddress2(Inet6Address sourceAddress) { byte[] b = sourceAddress.getAddress(); IPv6header.put(SOURCE_ADDRESS_OFFSET, b, 0, b.length); } /** * 获取目标地址 * @return 目标地址 */ public Inet6Address getDestinationAddress2() { byte[] b = new byte[IPV6_ADDRESS_LENGTH]; IPv6header.get(DESTINATION_ADDRESS_OFFSET, b, 0, b.length); try { return (Inet6Address) Inet6Address.getByAddress(b); } catch (UnknownHostException e) { return null; } } /** * 设置目标地址 * @param destinationAddress 目标地址 */ public void setDestinationAddress2(Inet6Address destinationAddress) { byte[] b = destinationAddress.getAddress(); IPv6header.put(DESTINATION_ADDRESS_OFFSET, b, 0, b.length); } /** * 获取流会话信息 * @return 流会话对象 */ public FlowSession getFlowSession() { return new FlowSession(getSourceAddress(), getDestinationAddress(), getFlowLabel()); } /** * 计算负载长度 * @return 负载长度 */ private int calcPayloadLength() { int lth = 0; for (int i = 0; i < headers.size(); i++) { int extHeaderLength=(int) headers.get(i).getTotalLength(); if(extHeaderLength<=0) { throw new IllegalArgumentException("extHeaderLength:"+extHeaderLength+"<0"); } lth += extHeaderLength; } lth += payload.getTotalLength(); return lth; } /** * 获取数据包总长度 * @return 数据包总长度 */ @Override public long getTotalLength() { return calcPayloadLength() + IPv6_HEADER_LENGTH; } /** * 将数据包写入通道 * @param dto 可写字节通道 * @throws IOException 写入异常 */ @Override public void writeToChannel(WritableByteChannel dto) throws IOException { if (headers.isEmpty()) { setNextHeader(payload.getProtocolNumber()); } else { setNextHeader(headers.get(0).getProtocolNumber()); } setPayloadLength(calcPayloadLength()); dto.write(IPv6header.slice(0, IPv6header.limit())); for (int i = 0; i < headers.size(); i++) { IPv6ExtHeader exth = headers.get(i); if (i + 1 < headers.size()) { exth.setNextHeader(headers.get(i + 1).getProtocolNumber()); } else { exth.setNextHeader(payload.getProtocolNumber()); } exth.writeToChannel(dto); } payload.writeToChannel(dto); if(debug) debug("send"); } /** * 从通道读取数据包 * @param din 可读字节通道 * @param length 数据长度 * @throws IOException 读取异常 */ @Override public void readFromChannel(ReadableByteChannel din, long length) throws IOException { IPv6header.limit(IPv6_HEADER_LENGTH); IPv6header.position(0); while (IPv6header.hasRemaining()) { if (din.read(IPv6header) == -1) { throw new EOFException(); } } int payloadlength = getPayloadLength(); int nextheader = getNextHeader(); loop: while (true) { IPv6ExtHeader ext; switch (nextheader) { case HOP_BY_HOP_OPTIONS: // Hop-by-Hop选项头部 ext = new IPv6HopByHopHeader(); ext.readFromChannel(din, 0); nextheader = ext.getNextHeader(); payloadlength -= ext.getTotalLength(); headers.add(ext); hopByHopHeader=(IPv6HopByHopHeader) ext; break; case DESTINATION_OPTIONS: // 目标选项头部 ext = new IPv6DestinationHeader(); ext.readFromChannel(din, 0); nextheader = ext.getNextHeader(); payloadlength -= ext.getTotalLength(); headers.add(ext); break; case ROUTING: // 路由头部 ByteBuffer bbf = NetworkPacket.bufferAllocator.allocate(2048); bbf.limit(4); while (bbf.hasRemaining()) { if (din.read(bbf) == -1) { throw new EOFException(); } } int routingType = bbf.get(2) & BIT_MASK_LOW_8_BITS; switch (routingType) { case SRV6_ROUTING_TYPE: // SRv6路由类型 ext = new IPv6SegmentRoutingHeader(bbf); break; default: // 其他路由类型 ext = new IPv6RoutingHeader(-1, bbf); break; } ext.readFromChannel(din, 0); nextheader = ext.getNextHeader(); payloadlength -= ext.getTotalLength(); headers.add(ext); routingHeader=(IPv6RoutingHeader) ext; break; case FRAGMENT: // 分段头部 ext = new IPv6ExtHeader(nextheader); ext.readFromChannel(din, 0); nextheader = ext.getNextHeader(); payloadlength -= ext.getTotalLength(); headers.add(ext); break; case ESP: // ESP头部 ext = new IPv6ExtHeader(nextheader); ext.readFromChannel(din, 0); nextheader = ext.getNextHeader(); payloadlength -= ext.getTotalLength(); headers.add(ext); break; case AH: // AH头部 ext = new IPv6ExtHeader(nextheader); ext.readFromChannel(din, 0); nextheader = ext.getNextHeader(); payloadlength -= ext.getTotalLength(); headers.add(ext); break; case NO_NEXT_HEADER: // 无下一个头部 ext = new IPv6ExtHeader(nextheader); ext.readFromChannel(din, 0); nextheader = ext.getNextHeader(); payloadlength -= ext.getTotalLength(); headers.add(ext); break; case ICMPv6: ICMPv6Packet icmp=ICMPv6Packet.readICMPv6PacketFromChannel(din,payloadlength); icmp.setParent(this); this.payload=icmp; break loop; case UDP: // UDP协议 UDPPacket udp=new UDPPacket(); udp.setParent(this); udp.readFromChannel(din,payloadlength); this.payload=udp; break loop; case KLALBPacket.KLALB_PROTOCOL_NUMBER: // KLALB协议 KLALBPacket kp = KLALBPacket.readKLALBPacketFromChannel(din); this.payload = kp; break loop; case KLTPPacket.KLTP_PROTOCOL_NUMBER: //KLTP协议 IPv6Payload epld = KLTPPacket.readKLTPPacketFromChannel(din); this.payload = epld; break loop; default: // 其他协议类型 IPv6Payload pld = new IPv6DefaultPayload(nextheader); pld.readFromChannel(din, payloadlength); this.payload = pld; break loop; } } if(debug) debug("recv"); } private void debug(String description) { StringBuilder sb=new StringBuilder(); sb.append(description); sb.append(" total:"); sb.append(getPayloadLength()); sb.append(" "); for (IPv6ExtHeader iPv6ExtHeader : headers) { sb.append(iPv6ExtHeader.getTotalLength()); sb.append(' '); } if(payload!=null) sb.append(payload.getTotalLength()); System.out.println(sb); } /** * 转换为字符串表示 * @return 字符串表示 */ @Override public String toString() { return "IPv6Packet [getVersion()=" + getVersion() + ", getTrafficClass()=" + getTrafficClass() + ", getFlowLabel()=" + getFlowLabel() + ", getPayloadLength()=" + getPayloadLength() + ", getNextHeader()=" + getNextHeader() + ", getHopLimit()=" + getHopLimit() + ", getSourceAddress()=" + getSourceAddress() + ", getDestinationAddress()=" + getDestinationAddress() + ", getLength()=" + getTotalLength() + ", headers=" + headers + ", payload=" + payload + "]"; } /** * IPv6负载数据类 */ public static abstract class IPv6Payload extends NetworkPacket { private IPv6Packet parent; private int protocolNumber; public IPv6Payload(int protocolNumber) { this.protocolNumber=protocolNumber; } public int getProtocolNumber() { return protocolNumber; } @Override protected boolean needEndPosition() { return true; } public void setParent(IPv6Packet parent) { this.parent = parent; } public IPv6Packet getParent() { return parent; } } public static class IPv6DefaultPayload extends IPv6Payload{ private ByteBuffer data; public ByteBuffer getData() { return data; } public IPv6DefaultPayload(int protocolNumber) { super(protocolNumber); this.data = NetworkPacket.bufferAllocator.allocate(65535); } public long getTotalLength() { return data.limit(); } @Override public void writeToChannel(WritableByteChannel dto) throws IOException { dto.write(data.slice(0, data.limit())); } @Override public void readFromChannel(ReadableByteChannel din, long length) throws IOException { data.limit((int) length); while (data.hasRemaining()) { if (din.read(data) == -1) { throw new EOFException(); } } } } /** * IPv6扩展头部基类 */ public static class IPv6ExtHeader extends NetworkPacket { private ByteBuffer data; private int protocolNumber; private int bufferLength; @Override public String toString() { return "IPv6ExtHeader [protocolNumber=" + protocolNumber + ", getNextHeader()=" + getNextHeader() + ", getExtLength()=" + getExtLength() + "]"; } public ByteBuffer getData() { return data; } public IPv6ExtHeader(int type) { this(type, -1); } protected IPv6ExtHeader(int protocolNumber, int bufferLength) { this.protocolNumber = protocolNumber; this.bufferLength=bufferLength; if (bufferLength==-1) { this.data = NetworkPacket.bufferAllocator.allocate(2048); } else { this.data = NetworkPacket.bufferAllocator.allocate(bufferLength); } } protected IPv6ExtHeader(int protocolNumber, int bufferLength, ByteBuffer data) { this.protocolNumber = protocolNumber; this.bufferLength = bufferLength; this.data = data; } public int getProtocolNumber() { return protocolNumber; } public int getNextHeader() { return data.get(0) & BIT_MASK_LOW_8_BITS; } public void setNextHeader(int nextHeader) { data.put(0, (byte) nextHeader); } public int getExtLength() { return data.get(1) & BIT_MASK_LOW_8_BITS; } protected void setExtLength(int extLength) { data.put(1, (byte) extLength); } public long getTotalLength() { return data.limit(); } @Override public void writeToChannel(WritableByteChannel dto) throws IOException { if (bufferLength==-1) { int ext = (data.limit() - EXT_HEADER_ALIGNMENT) / EXT_HEADER_ALIGNMENT; setExtLength(ext); dto.write(data.slice(0, data.limit())); } else { dto.write(data.slice(0, bufferLength)); } } @Override public void readFromChannel(ReadableByteChannel din, long length) throws IOException { data.limit(bufferLength); while (data.hasRemaining()) { if (din.read(data) == -1) { throw new EOFException(); } } if (bufferLength==-1) { int newLimit = getExtLength() * EXT_HEADER_ALIGNMENT + data.limit(); data.limit(newLimit); while (data.hasRemaining()) { if (din.read(data) == -1) { throw new EOFException(); } } } } @Override protected boolean needEndPosition() { return false; } } /** * IPv6逐跳头部类 */ public static class IPv6HopByHopHeader extends IPv6ExtHeader { private final List tlvs = new ArrayList(); @Override public String toString() { return "IPv6HopByHopHeader [tlvs=" + tlvs + ", getProtocolNumber()=" + getProtocolNumber() + ", getNextHeader()=" + getNextHeader() + ", getExtLength()=" + getExtLength() + "]"; } public IPv6HopByHopHeader() { super(HOP_BY_HOP_OPTIONS,2); } public IPv6HopByHopHeader( ByteBuffer data) { super(HOP_BY_HOP_OPTIONS, 2, data); } @Override public void writeToChannel(WritableByteChannel dto) throws IOException { int exl = calcTLVLength(); if ((exl+2) % EXT_HEADER_ALIGNMENT != 0) { throw new StreamCorruptedException("extLength % " + EXT_HEADER_ALIGNMENT + " !=0"); } setExtLength(((exl+2) / EXT_HEADER_ALIGNMENT)-1); super.writeToChannel(dto); for (IPv6HopByHopTLV tlv : tlvs) { IPv6HopByHopTLV.writeIPv6HopByHopTLVToChannel(dto, tlv); } } private int calcTLVLength() { int tlvsl = 0; for (IPv6HopByHopTLV tlve : tlvs) { tlvsl += tlve.getTotalLength(); } return tlvsl; } @Override public void readFromChannel(ReadableByteChannel din, long length) throws IOException { super.readFromChannel(din, length); int extl = getExtLength(); // 计算应该读取的总字节数 int expectedTotalBytes = (extl + 1) * EXT_HEADER_ALIGNMENT; int tlvBytesToRead = expectedTotalBytes - 2; // 减去基础头的2字节 tlvs.clear(); int bytesRead = 0; // 读取直到达到预期的字节数 while (bytesRead < tlvBytesToRead) { IPv6HopByHopTLV tlv = IPv6HopByHopTLV.readIPv6HopByHopTLVFromChannel(din); int tlvLength = (int) tlv.getTotalLength(); // 检查是否会超出预期范围 if (bytesRead + tlvLength > tlvBytesToRead) { throw new StreamCorruptedException( String.format("TLV overflow: read %d + %d > %d bytes", bytesRead, tlvLength, tlvBytesToRead)); } tlvs.add(tlv); bytesRead += tlvLength; } // 验证实际读取的字节数与预期一致 if (bytesRead != tlvBytesToRead) { throw new StreamCorruptedException( String.format("TLV length mismatch: expected %d, got %d", tlvBytesToRead, bytesRead)); } } @Override public long getTotalLength() { return calcTLVLength() + 2; } public List getTlvs() { return tlvs; } } /** * IPv6路由头部类 */ public static class IPv6RoutingHeader extends IPv6ExtHeader { @Override public String toString() { return "IPv6RoutingHeader [protocolNumber=" + getProtocolNumber() + ", getNextHeader()=" + getNextHeader() + ", getExtLength()=" + getExtLength() + ", getRoutingType()=" + getRoutingType() + "]"; } public IPv6RoutingHeader() { super(ROUTING); } public IPv6RoutingHeader(int bufferLength) { super(ROUTING, bufferLength); } public IPv6RoutingHeader(int bufferLength, ByteBuffer data) { super(ROUTING, bufferLength, data); } public int getRoutingType() { return getData().get(2) & BIT_MASK_LOW_8_BITS; } public void setRoutingType(int routingTypr) { getData().put(2, (byte) routingTypr); } public int getSegmentsLeft() { return getData().get(3); } public void setSegmentsLeft(int segmentsLeft) { getData().put(3, (byte) segmentsLeft); } } /** * IPv6段路由头部类 */ /** * IPv6 Segment Routing Header (SRH) 实现 * *

根据 RFC 8754 实现,支持SRv6扩展头和TLV选项

* *
     *   0                   1                   2                   3
     *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     *  | Next Header   |  Hdr Ext Len  | Routing Type  | Segments Left |
     *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     *  |     Last Entry    |     Flags     |              Tag          |
     *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     *  |                                                               |
     *  |            Segment List[0] (128-bit IPv6 address)            |
     *  |                                                               |
     *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     *  |                               ...                             |
     *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     *  |                                                               |
     *  |            Segment List[n] (128-bit IPv6 address)            |
     *  |                                                               |
     *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     *  //                                                             //
     *  //         Optional Type-Length-Value objects (variable)       //
     *  //                                                             //
     *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     * 
*/ public static class IPv6SegmentRoutingHeader extends IPv6RoutingHeader { private final List addresses = new ArrayList(); private final List tlvs = new ArrayList(); @Override public String toString() { return "IPv6SegmentRoutingHeader [addresses=" + addresses + ", tlvs=" + tlvs + ", getLastEntry()=" + getLastEntry() + ", getFlags()=" + getFlags() + ", getTag()=" + getTag() + ", getAddresses()=" + getAddresses() + ", getRoutingType()=" + getRoutingType() + ", getSegmentsLeft()=" + getSegmentsLeft() + ", getProtocolNumber()=" + getProtocolNumber() + ", getNextHeader()=" + getNextHeader() + ", getExtLength()=" + getExtLength() + "]"; } public IPv6SegmentRoutingHeader() { super(EXT_HEADER_ALIGNMENT); setRoutingType(SRV6_ROUTING_TYPE); } public IPv6SegmentRoutingHeader(ByteBuffer bbf) { super(EXT_HEADER_ALIGNMENT, bbf); } public IPv6SegmentRoutingHeader(List segs) { this(); this.addresses.addAll(segs); resetSegmentPos(); } public void resetSegmentPos() { int ln = addresses.size() - 1; setLastEntry(ln); setSegmentsLeft(ln); } public int getLastEntry() { return getData().get(4) & BIT_MASK_LOW_8_BITS; } public void setLastEntry(int lastEntry) { getData().put(4, (byte) lastEntry); } public int getFlags() { return getData().get(5) & BIT_MASK_LOW_8_BITS; } public void setFlags(int flags) { getData().put(5, (byte) flags); } public int getTag() { return getData().getShort(6) & BIT_MASK_LOW_16_BITS; } public void setTag(int tag) { getData().putShort(6, (short) tag); } public List getAddresses() { return addresses; } public List getTlvs() { return tlvs; } @Override public void writeToChannel(WritableByteChannel dto) throws IOException { int exl = calcExtLength(); if (exl % EXT_HEADER_ALIGNMENT != 0) { throw new StreamCorruptedException("extLength % " + EXT_HEADER_ALIGNMENT + " !=0"); } setExtLength(exl / EXT_HEADER_ALIGNMENT); setLastEntry(addresses.size() - 1); super.writeToChannel(dto); ByteBuffer addr=NetworkPacket.bufferAllocator.allocateHeap(addresses.size() *IPV6_ADDRESS_LENGTH); for (IPv6Address inet6Address : addresses) { inet6Address.writeTo(addr); } addr.flip(); dto.write(addr); for (IPv6SegmentRoutingTLV tlv : tlvs) { IPv6SegmentRoutingTLV.writeIPv6SegmentRoutingTLVToChannel(dto, tlv); } } private int calcExtLength() { int tlvsl = 0; for (IPv6SegmentRoutingTLV tlve : tlvs) { tlvsl += tlve.getTotalLength(); } return addresses.size() * IPV6_ADDRESS_LENGTH + tlvsl; } /*@Override public void readFromChannel(ReadableByteChannel din, long length) throws IOException { super.readFromChannel(din, length); int extl = getExtLength(); int laste = getLastEntry(); int rl = extl * EXT_HEADER_ALIGNMENT; int usdl = 0; // System.out.println("SR length:"+(laste+1)); addresses.clear(); ByteBuffer bfr = NetworkPacket.bufferAllocator.allocateHeap(IPV6_ADDRESS_LENGTH); for (int i = 0; i < (laste + 1); i++) { bfr.clear(); while (bfr.hasRemaining()) { if (din.read(bfr) == -1) { throw new EOFException(); } } bfr.flip(); usdl += bfr.limit(); Inet6Address addr = (Inet6Address) Inet6Address.getByAddress(bfr.array()); // System.out.println("SR:"+addr); addresses.add(addr); } tlvs.clear(); while (usdl < rl) { IPv6SegmentRoutingTLV tlv = IPv6SegmentRoutingTLV.readIPv6SegmentRoutingTLVFromChannel(din); usdl += tlv.getTotalLength(); tlvs.add(tlv); } return; }*/ @Override public void readFromChannel(ReadableByteChannel din, long length) throws IOException { super.readFromChannel(din, length); ByteBuffer bfr = null; int extl = getExtLength(); int laste = getLastEntry(); int rl = extl * EXT_HEADER_ALIGNMENT; int usdl = 0; // 验证lastEntry的合理性 if (laste < 0 ) { throw new StreamCorruptedException("Invalid lastEntry: " + laste); } addresses.clear(); bfr = NetworkPacket.bufferAllocator.allocateHeap(IPV6_ADDRESS_LENGTH*(laste+1)); KNEChannels.readFully(din, bfr); bfr.flip(); usdl += bfr.limit(); for (int i = 0; i <= laste; i++) { // 注意:应该是 <= laste addresses.add(IPv6Address.valueOf(bfr)); } tlvs.clear(); while (usdl < rl) { IPv6SegmentRoutingTLV tlv = IPv6SegmentRoutingTLV.readIPv6SegmentRoutingTLVFromChannel(din); usdl += tlv.getTotalLength(); tlvs.add(tlv); } // 验证读取的字节数与预期一致 if (usdl != rl) { throw new StreamCorruptedException("Length mismatch: expected " + rl + ", got " + usdl); } } // 辅助方法:确保读取完整数据 private int readFully(ReadableByteChannel channel, ByteBuffer buffer) throws IOException { int totalRead = 0; while (buffer.hasRemaining()) { int read = channel.read(buffer); if (read == -1) { break; } totalRead += read; } return totalRead; } @Override public long getTotalLength() { return calcExtLength() + EXT_HEADER_ALIGNMENT; } } /** * IPv6目标选项头部类 */ public static class IPv6DestinationHeader extends IPv6ExtHeader { @Override public String toString() { return "IPv6DestinationHeader [protocolNumber=" + getProtocolNumber() + ", getNextHeader()=" + getNextHeader() + ", getExtLength()=" + getExtLength() + ", getRoutingType()=" + getRoutingType() + "]"; } public IPv6DestinationHeader() { super(DESTINATION_OPTIONS); } public int getRoutingType() { return getData().get(2) & BIT_MASK_LOW_8_BITS; } public void setRoutingType(int routingTypr) { getData().put(2, (byte) routingTypr); } public int getSegmentsLeft() { return getData().get(3); } public void setSegmentsLeft(int segmentsLeft) { getData().put(3, (byte) segmentsLeft); } } /** * 获取所有扩展头部 * @return 扩展头部列表 */ public List getHeaders() { return headers; } /** * 获取IPv6逐跳头部 * @return IPv6段逐跳头部,如果不存在则返回null */ public IPv6HopByHopHeader getHopByHopHeader() { return hopByHopHeader; } /** * 获取路由头部 * @return 路由头部,如果不存在则返回null */ public IPv6RoutingHeader getRoutingHeader() { return routingHeader; } public void setHopByHopHeader(IPv6HopByHopHeader hopByHopHeader) { this.hopByHopHeader = hopByHopHeader; } public void setRoutingHeader(IPv6RoutingHeader routingHeader) { this.routingHeader = routingHeader; } /** * 获取SRv6段路由头部 * @return SRv6段路由头部,如果不存在则返回null */ public IPv6SegmentRoutingHeader getSegmentRoutingHeader() { IPv6RoutingHeader rh=getRoutingHeader(); if(rh==null) return null; IPv6SegmentRoutingHeader srhh=null; if (rh instanceof IPv6SegmentRoutingHeader) { if (((IPv6SegmentRoutingHeader) rh).getRoutingType() == SRV6_ROUTING_TYPE) { srhh = (IPv6SegmentRoutingHeader) rh; } } return srhh; } public UUID getPacketID() { IPv6HopByHopHeader hop=getHopByHopHeader(); if(hop==null) return null; List tlvs= hop.getTlvs(); for(IPv6HopByHopTLV tlv:tlvs) { if(tlv instanceof KLALBOAMHopByHopTLV) return ((KLALBOAMHopByHopTLV)tlv).getUUID(); } return null; } @Override protected boolean needEndPosition() { return false; } // 重路由计数器 private AtomicInteger rerouteCounter = new AtomicInteger(0); public AtomicInteger getRerouteCounter() { return rerouteCounter; } public long calculateAddressChecksum() { long sum=0; ByteBuffer dataCopy = IPv6header.slice(SOURCE_ADDRESS_OFFSET,32); while (dataCopy.remaining() >= 2) { sum += dataCopy.getChar(); } if (dataCopy.remaining() == 1) { sum += (dataCopy.get() & 0xFF) << 8; } return sum; } }