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<IPv6ExtHeader> 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<IPv6HopByHopTLV> tlvs = new ArrayList<IPv6HopByHopTLV>();
        @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<IPv6HopByHopTLV> 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) 实现
     * 
     * <p>根据 RFC 8754 实现，支持SRv6扩展头和TLV选项</p>
     * 
     * <pre>
     *   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)       //
     *  //                                                             //
     *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     * </pre>
     */
    public static class IPv6SegmentRoutingHeader extends IPv6RoutingHeader {

        private final List<IPv6Address> addresses = new ArrayList<IPv6Address>();
        private final List<IPv6SegmentRoutingTLV> tlvs = new ArrayList<IPv6SegmentRoutingTLV>();

        @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<IPv6Address> 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<IPv6Address> getAddresses() {
            return addresses;
        }

        public List<IPv6SegmentRoutingTLV> 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<IPv6ExtHeader> 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<IPv6HopByHopTLV> 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;
	}


	

}