private SocketError OnBind(IntPtr socket, IntPtr address, int addressSize) { var socketAddress = GetSocketAddress(address); DebugMessage( nameof(OnBind), "Binding to `{0}:{1}` ...", socketAddress?.Address?.IPAddress, socketAddress?.Port ); var networkInterface = GetNetworkInterface(); var interfaceAddress = GetInterfaceAddress(networkInterface, socketAddress?.AddressFamily, true); if (socketAddress?.Address == null || networkInterface == null || interfaceAddress == null) { DebugMessage( nameof(OnBind), "Binding to `{0}:{1}` rejected due to lack of a valid interface address.", socketAddress?.Address?.IPAddress, socketAddress?.Port ); return(SocketError.SocketError); } SocketError bindResult; if (interfaceAddress.AddressFamily == AddressFamily.InterNetwork && !interfaceAddress.Equals(socketAddress.Address.IPAddress)) { var bindIn = new SocketAddressIn { Address = new AddressIn { IPAddress = interfaceAddress }, AddressFamily = interfaceAddress.AddressFamily, Port = socketAddress.Port }; DebugMessage( nameof(OnBind), "Binding to `{0}:{1}` replaced by a binding request to `{2}:{3}`.", socketAddress.Address.IPAddress, socketAddress.Port, bindIn.Address.IPAddress, bindIn.Port ); socketAddress = bindIn; bindResult = Socket.Bind(socket, ref bindIn, Marshal.SizeOf(bindIn)); } else if (interfaceAddress.AddressFamily == AddressFamily.InterNetworkV6 && !interfaceAddress.Equals(socketAddress.Address.IPAddress)) { var scopeId = (uint?)networkInterface.GetIPProperties()?.GetIPv6Properties()?.Index ?? 0; var flowInfo = (socketAddress as SocketAddressIn6?)?.FlowInfo ?? 0; var bindIn6 = new SocketAddressIn6 { Address = new AddressIn6 { IPAddress = interfaceAddress }, AddressFamily = interfaceAddress.AddressFamily, Port = socketAddress.Port, // Assign a random port ScopeId = scopeId, FlowInfo = flowInfo }; DebugMessage( nameof(OnBind), "Binding to `{0}:{1}` replaced by a binding request to `{2}:{3}`.", socketAddress.Address.IPAddress, socketAddress.Port, bindIn6.Address.IPAddress, bindIn6.Port ); socketAddress = bindIn6; bindResult = Socket.Bind(socket, ref bindIn6, Marshal.SizeOf(bindIn6)); } else { bindResult = Socket.Bind(socket, address, addressSize); } DebugMessage( nameof(OnBind), "Binding to `{0}:{1}` resulted in a `{2}` response. [WSALastError = `{3}`]", socketAddress.Address.IPAddress, socketAddress.Port, bindResult, Socket.WSAGetLastError() ); return(bindResult); }
private SocketError BindSocketByAddress(IntPtr socket, ISocketAddress socketAddress) { switch (socketAddress?.AddressFamily) { case AddressFamily.InterNetwork: if (socketAddress.Address?.IPAddress?.Equals(IPAddress.Any) == true) { DebugMessage( nameof(BindSocketByAddress), "Binding to interface skipped due to the nature of passed IP Address. [0.0.0.0]" ); return(SocketError.Success); } if (IsIpInRange(socketAddress.Address?.IPAddress, IPAddress.Parse("127.0.0.0"), IPAddress.Parse("127.255.255.255"))) { DebugMessage( nameof(BindSocketByAddress), "Binding to interface skipped due to the nature of passed IP Address. [Loop Back]" ); return(SocketError.Success); // LoopBack } if (IsIpInRange(socketAddress.Address?.IPAddress, IPAddress.Parse("10.0.0.0"), IPAddress.Parse("10.255.255.255"))) { DebugMessage( nameof(BindSocketByAddress), "Binding to interface skipped due to the nature of passed IP Address. [Private Range]" ); return(SocketError.Success); // Private Network } if (IsIpInRange(socketAddress.Address?.IPAddress, IPAddress.Parse("172.16.0.0"), IPAddress.Parse("172.31.255.255"))) { DebugMessage( nameof(BindSocketByAddress), "Binding to interface skipped due to the nature of passed IP Address. [Private Range]" ); return(SocketError.Success); // Private Network } if (IsIpInRange(socketAddress.Address?.IPAddress, IPAddress.Parse("192.168.0.0"), IPAddress.Parse("192.168.255.255"))) { DebugMessage( nameof(BindSocketByAddress), "Binding to interface skipped due to the nature of passed IP Address. [Private Range]" ); return(SocketError.Success); // Private Network } if (IsIpInRange(socketAddress.Address?.IPAddress, IPAddress.Parse("169.254.1.0"), IPAddress.Parse("169.254.254.255"))) { DebugMessage( nameof(BindSocketByAddress), "Binding to interface skipped due to the nature of passed IP Address. [Link Local Network]" ); return(SocketError.Success); // Link Local Network } if (IsIpInRange(socketAddress.Address?.IPAddress, IPAddress.Parse("224.0.0.0"), IPAddress.Parse("239.255.255.255"))) { DebugMessage( nameof(BindSocketByAddress), "Binding to interface skipped due to the nature of passed IP Address. [MultiCast Address]" ); return(SocketError.Success); // MultiCast } break; case AddressFamily.InterNetworkV6: if (socketAddress.Address?.IPAddress?.Equals(IPAddress.IPv6Any) == true) { DebugMessage( nameof(BindSocketByAddress), "Binding to interface skipped due to the nature of passed IP Address. [0000:]" ); return(SocketError.Success); } if (socketAddress.Address?.IPAddress?.Equals(IPAddress.IPv6Loopback) == true) { DebugMessage( nameof(BindSocketByAddress), "Binding to interface skipped due to the nature of passed IP Address. [Loop Back]" ); return(SocketError.Success); // LoopBack } if (IsIpInRange(socketAddress.Address?.IPAddress, IPAddress.Parse("fc00:0000:0000:0000:0000:0000:0000:0000"), IPAddress.Parse("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"))) { DebugMessage( nameof(BindSocketByAddress), "Binding to interface skipped due to the nature of passed IP Address. [fc00:]" ); return(SocketError.Success); // Unique Local Addresses, Private networks, MultiCast } break; default: DebugMessage( nameof(BindSocketByAddress), "Binding to interface skipped due an unsupported address family of `{0}`.", socketAddress?.AddressFamily ); return(SocketError.Success); } var networkInterface = GetNetworkInterface(); var interfaceAddress = GetInterfaceAddress(networkInterface, socketAddress.AddressFamily, false); if (networkInterface == null || interfaceAddress == null) { DebugMessage( nameof(OnBind), "Binding for the `{0}:{1}` rejected due to lack of a valid interface address.", socketAddress.Address?.IPAddress, socketAddress.Port ); return(SocketError.SocketError); } if (interfaceAddress.AddressFamily == AddressFamily.InterNetwork) { var bindIn = new SocketAddressIn { Address = new AddressIn { IPAddress = interfaceAddress }, AddressFamily = interfaceAddress.AddressFamily, Port = 0 // Assign a random port }; DebugMessage( nameof(BindSocketByAddress), "Binding to `{0}:{1}` ...", bindIn.Address?.IPAddress, bindIn.Port ); return(Socket.Bind(socket, ref bindIn, Marshal.SizeOf(bindIn))); } if (interfaceAddress.AddressFamily == AddressFamily.InterNetworkV6) { var scopeId = (uint?)networkInterface.GetIPProperties()?.GetIPv6Properties()?.Index ?? 0; var flowInfo = (socketAddress as SocketAddressIn6?)?.FlowInfo ?? 0; var bindIn6 = new SocketAddressIn6 { Address = new AddressIn6 { IPAddress = interfaceAddress }, AddressFamily = interfaceAddress.AddressFamily, Port = 0, // Assign a random port ScopeId = scopeId, FlowInfo = flowInfo }; DebugMessage( nameof(BindSocketByAddress), "Binding to `{0}:{1}` ...", bindIn6.Address?.IPAddress, bindIn6.Port ); return(Socket.Bind(socket, ref bindIn6, Marshal.SizeOf(bindIn6))); } DebugMessage( nameof(BindSocketByAddress), "Binding to interface skipped due an unsupported interface address family of `{0}`.", interfaceAddress.AddressFamily ); return(SocketError.Success); }