.net core linux下使用getsockopt获取源IP

使用linux的NAT功能可以把网络流量转发到特定端口上,然后我们可以写一个程序来处理这个端口上的数据,通过一些操作转发到对应服务器上来实现透明代理功能。

前段时间闲来无事研究了一下在.net core下如何做这些事情。下面是获取通过NAT转发过的数据包的源IP,端口信息的部分逻辑。

主要使用了libc下的getsockopt来获取源信息,对应的c语言代码网上可以找到很多,下面是用.net core的实现。

 [DllImport("libc" ,CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
        private static unsafe extern int getsockopt(IntPtr socket, SocketLevel level, SocketOptionName option_name,void* option_value, ref int option_len);
      
        public unsafe static IPEndPoint GetTCPOriginAddr(IntPtr handle)
        {
            var size = 128;
            var buff = stackalloc byte[size];
            int r = getsockopt(handle, SocketLevel.SOL_IP, SocketOptionName.SO_ORIGINAL_DST, buff, ref size);
            if (r != 0)
            {
                r = getsockopt(handle, SocketLevel.SOL_IPV6, SocketOptionName.SO_ORIGINAL_DST, buff, ref size);
                if (r != 0)
                    throw new Exception("can not get dst addr");
            }
            return new IPEndPoint(GetNetIP(buff), GetNetPort(buff));
        }
        public static unsafe IPAddress GetIPV4(byte* buff, ref int pos)
        {
            //大端法机器
            uint result = GetNetIP(buff);
            return IPAddress.Parse(result.ToString());
        }
        public static unsafe uint GetNetIP(byte* buff, int offset = 0)
        {
            //大端法机器
            uint result = 0;
            result |= (uint)buff[offset + 4 + 0];
            result |= (uint)buff[offset + 4 + 1] << 8;
            result |= (uint)buff[offset + 4 + 2] << 16;
            result |= (uint)buff[offset + 4 + 3] << 24;
            return result;
        }
        public static unsafe ushort GetNetPort(byte* buff, int offset = 0)
        {
            //大端法机器
            ushort result = 0;
            result |= (ushort)buff[offset + 2 + 1];
            result |= (ushort)(buff[offset + 2 + 0] << 8);
            return result;
        }

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注