IP地址 “V6ToV4,V4ToV6” 转换函数实现

53 篇文章 2 订阅

注意本文实现的 “V6ToV4,V4ToV6” 是给操作系统用的,如 Linux/Windows,而不是搞特殊标准,即 “2001/2002” 开头的映射V6地址格式。

2001:IANA特殊地址 Teredo隧道地址。

2002:是V6转V4地址,由用户端设备自动建立,通过隧道技术连接至IPv6 互联网,不是运营商管理和分配的,服务质量与运营商无关。

话是这么说的,但实际上不是所有的运营商都按这个套路来的,有些需要加运营商给你的特殊IPV6前缀才能实现,IPV6访问IPV4资源,所以不要看到2002就沸腾了,这东西不一定能用。

Linux/Windows 系统上面V4地址转换为V6地址格式为:

IPV4:1.1.1.1

IPV6:::FFFF:1.1.1.1 展开 0000:0000:0000:0000:0000:FFFF:1.1.1.1

关键数据结构

        [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 16)]
        private struct IPV62V4ADDR
        {
            [FieldOffset(0)]
            public long R1;

            [FieldOffset(8)]
            public ushort R2;

            [FieldOffset(10)]
            public ushort R3;

            [FieldOffset(12)]
            public uint R4;
        }

V6ToV4(V6地址转换为V4地址)

#if NETCOREAPP
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        [SecurityCritical]
        [SecuritySafeCritical]
        public static IPEndPoint V6ToV4(IPEndPoint address)
        {
            if (address == null)
            {
                return null;
            }
            IPAddress host = IPFrame.V6ToV4(address.Address);
            if (host == null)
            {
                return null;
            }
            return new IPEndPoint(host, address.Port);
        }

#if NETCOREAPP
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        [SecurityCritical]
        [SecuritySafeCritical]
        public static IPAddress V6ToV4(IPAddress address)
        {
            if (address == null)
            {
                return null;
            }

            if (address.AddressFamily == AddressFamily.InterNetwork)
            {
                return address;
            }

            byte[] buff = address.GetAddressBytes();
            fixed (byte* chunk = buff)
            {
                IPV62V4ADDR* p = (IPV62V4ADDR*)chunk;
                if (p->R1 != 0 || p->R2 != 0)
                {
                    return null;
                }
                if (p->R3 != ushort.MaxValue)
                {
                    return null;
                }
                return new IPAddress(p->R4);
            }
        }

V4ToV6(V4地址转换为V6地址)

#if NETCOREAPP
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        [SecurityCritical]
        [SecuritySafeCritical]
        public static IPEndPoint V4ToV6(IPEndPoint address)
        {
            if (address == null)
            {
                return null;
            }
            IPAddress host = IPFrame.V4ToV6(address.Address);
            if (host == null)
            {
                return null;
            }
            return new IPEndPoint(host, address.Port);
        }

#if NETCOREAPP
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        [SecurityCritical]
        [SecuritySafeCritical]
        public static IPAddress V4ToV6(IPAddress address)
        {
            if (address == null)
            {
                return null;
            }
            if (address.AddressFamily == AddressFamily.InterNetwork)
            {
                byte[] buff = new byte[16];
                fixed (byte* chunk = buff)
                {
                    fixed (byte* v4 = address.GetAddressBytes())
                    {
                        IPV62V4ADDR* p = (IPV62V4ADDR*)chunk;
                        p->R3 = ushort.MaxValue;
                        p->R4 = *(uint*)v4;
                    }
                }
                return new IPAddress(buff);
            }
            return address;
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值