diff --git a/Ryujinx.HLE/HOS/Services/Bsd/BsdError.cs b/Ryujinx.HLE/HOS/Services/Bsd/BsdError.cs
deleted file mode 100644
index 675edcc3dd..0000000000
--- a/Ryujinx.HLE/HOS/Services/Bsd/BsdError.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Bsd
-{
-    //bsd_errno == (SocketException.ErrorCode - 10000)
-    enum BsdError
-    {
-        Timeout = 60
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Bsd/BsdIoctl.cs b/Ryujinx.HLE/HOS/Services/Bsd/BsdIoctl.cs
new file mode 100644
index 0000000000..15fc7a8278
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Bsd/BsdIoctl.cs
@@ -0,0 +1,7 @@
+namespace Ryujinx.HLE.HOS.Services.Bsd
+{
+    enum BsdIoctl
+    {
+        AtMark = 0x40047307,
+    }
+}
diff --git a/Ryujinx.HLE/HOS/Services/Bsd/BsdSocket.cs b/Ryujinx.HLE/HOS/Services/Bsd/BsdSocket.cs
index 2361ed31b7..2786da1364 100644
--- a/Ryujinx.HLE/HOS/Services/Bsd/BsdSocket.cs
+++ b/Ryujinx.HLE/HOS/Services/Bsd/BsdSocket.cs
@@ -1,4 +1,3 @@
-using System.Net;
 using System.Net.Sockets;
 
 namespace Ryujinx.HLE.HOS.Services.Bsd
@@ -9,10 +8,6 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
         public int Type;
         public int Protocol;
 
-        public IPAddress IpAddress;
-
-        public IPEndPoint RemoteEP;
-
         public Socket Handle;
     }
 }
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Bsd/IClient.cs b/Ryujinx.HLE/HOS/Services/Bsd/IClient.cs
index e2cd0dcdb7..37d0fcfdba 100644
--- a/Ryujinx.HLE/HOS/Services/Bsd/IClient.cs
+++ b/Ryujinx.HLE/HOS/Services/Bsd/IClient.cs
@@ -1,45 +1,265 @@
+using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Ipc;
 using Ryujinx.HLE.Utilities;
 using System.Collections.Generic;
-using System.IO;
 using System.Net;
 using System.Net.Sockets;
-using System.Threading.Tasks;
+using System.Text;
 
 namespace Ryujinx.HLE.HOS.Services.Bsd
 {
     class IClient : IpcService
     {
+
+        private static Dictionary<WSAError, LinuxError> ErrorMap = new Dictionary<WSAError, LinuxError>
+        {
+            // WSAEINTR
+            {WSAError.WSAEINTR,           LinuxError.EINTR},
+            // WSAEWOULDBLOCK
+            {WSAError.WSAEWOULDBLOCK,     LinuxError.EWOULDBLOCK},
+            // WSAEINPROGRESS
+            {WSAError.WSAEINPROGRESS,     LinuxError.EINPROGRESS},
+            // WSAEALREADY
+            {WSAError.WSAEALREADY,        LinuxError.EALREADY},
+            // WSAENOTSOCK
+            {WSAError.WSAENOTSOCK,        LinuxError.ENOTSOCK},
+            // WSAEDESTADDRREQ
+            {WSAError.WSAEDESTADDRREQ,    LinuxError.EDESTADDRREQ},
+            // WSAEMSGSIZE
+            {WSAError.WSAEMSGSIZE,        LinuxError.EMSGSIZE},
+            // WSAEPROTOTYPE
+            {WSAError.WSAEPROTOTYPE,      LinuxError.EPROTOTYPE},
+            // WSAENOPROTOOPT
+            {WSAError.WSAENOPROTOOPT,     LinuxError.ENOPROTOOPT},
+            // WSAEPROTONOSUPPORT
+            {WSAError.WSAEPROTONOSUPPORT, LinuxError.EPROTONOSUPPORT},
+            // WSAESOCKTNOSUPPORT
+            {WSAError.WSAESOCKTNOSUPPORT, LinuxError.ESOCKTNOSUPPORT},
+            // WSAEOPNOTSUPP
+            {WSAError.WSAEOPNOTSUPP,      LinuxError.EOPNOTSUPP},
+            // WSAEPFNOSUPPORT
+            {WSAError.WSAEPFNOSUPPORT,    LinuxError.EPFNOSUPPORT},
+            // WSAEAFNOSUPPORT
+            {WSAError.WSAEAFNOSUPPORT,    LinuxError.EAFNOSUPPORT},
+            // WSAEADDRINUSE
+            {WSAError.WSAEADDRINUSE,      LinuxError.EADDRINUSE},
+            // WSAEADDRNOTAVAIL
+            {WSAError.WSAEADDRNOTAVAIL,   LinuxError.EADDRNOTAVAIL},
+            // WSAENETDOWN
+            {WSAError.WSAENETDOWN,        LinuxError.ENETDOWN},
+            // WSAENETUNREACH
+            {WSAError.WSAENETUNREACH,     LinuxError.ENETUNREACH},
+            // WSAENETRESET
+            {WSAError.WSAENETRESET,       LinuxError.ENETRESET},
+            // WSAECONNABORTED
+            {WSAError.WSAECONNABORTED,    LinuxError.ECONNABORTED},
+            // WSAECONNRESET
+            {WSAError.WSAECONNRESET,      LinuxError.ECONNRESET},
+            // WSAENOBUFS
+            {WSAError.WSAENOBUFS,         LinuxError.ENOBUFS},
+            // WSAEISCONN
+            {WSAError.WSAEISCONN,         LinuxError.EISCONN},
+            // WSAENOTCONN
+            {WSAError.WSAENOTCONN,        LinuxError.ENOTCONN},
+            // WSAESHUTDOWN
+            {WSAError.WSAESHUTDOWN,       LinuxError.ESHUTDOWN},
+            // WSAETOOMANYREFS
+            {WSAError.WSAETOOMANYREFS,    LinuxError.ETOOMANYREFS},
+            // WSAETIMEDOUT
+            {WSAError.WSAETIMEDOUT,       LinuxError.ETIMEDOUT},
+            // WSAECONNREFUSED
+            {WSAError.WSAECONNREFUSED,    LinuxError.ECONNREFUSED},
+            // WSAELOOP
+            {WSAError.WSAELOOP,           LinuxError.ELOOP},
+            // WSAENAMETOOLONG
+            {WSAError.WSAENAMETOOLONG,    LinuxError.ENAMETOOLONG},
+            // WSAEHOSTDOWN
+            {WSAError.WSAEHOSTDOWN,       LinuxError.EHOSTDOWN},
+            // WSAEHOSTUNREACH
+            {WSAError.WSAEHOSTUNREACH,    LinuxError.EHOSTUNREACH},
+            // WSAENOTEMPTY
+            {WSAError.WSAENOTEMPTY,       LinuxError.ENOTEMPTY},
+            // WSAEUSERS
+            {WSAError.WSAEUSERS,          LinuxError.EUSERS},
+            // WSAEDQUOT
+            {WSAError.WSAEDQUOT,          LinuxError.EDQUOT},
+            // WSAESTALE
+            {WSAError.WSAESTALE,          LinuxError.ESTALE},
+            // WSAEREMOTE
+            {WSAError.WSAEREMOTE,         LinuxError.EREMOTE},
+            // WSAEINVAL
+            {WSAError.WSAEINVAL,          LinuxError.EINVAL},
+            // WSAEFAULT
+            {WSAError.WSAEFAULT,          LinuxError.EFAULT},
+            // NOERROR
+            {0, 0}
+        };
+
         private Dictionary<int, ServiceProcessRequest> m_Commands;
 
         public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
 
+        private bool IsPrivileged;
+
         private List<BsdSocket> Sockets = new List<BsdSocket>();
 
-        public IClient()
+        public IClient(bool IsPrivileged)
         {
             m_Commands = new Dictionary<int, ServiceProcessRequest>()
             {
-                { 0,  Initialize      },
-                { 1,  StartMonitoring },
-                { 2,  Socket          },
-                { 6,  Poll            },
-                { 8,  Recv            },
-                { 10, Send            },
-                { 11, SendTo          },
-                { 12, Accept          },
-                { 13, Bind            },
-                { 14, Connect         },
-                { 18, Listen          },
-                { 21, SetSockOpt      },
-                { 24, Write           },
-                { 25, Read            },
-                { 26, Close           }
+                { 0,  RegisterClient     },
+                { 1,  StartMonitoring    },
+                { 2,  Socket             },
+                { 3,  SocketExempt       },
+                { 4,  Open               },
+                { 5,  Select             },
+                { 6,  Poll               },
+                { 7,  Sysctl             },
+                { 8,  Recv               },
+                { 9,  RecvFrom           },
+                { 10, Send               },
+                { 11, SendTo             },
+                { 12, Accept             },
+                { 13, Bind               },
+                { 14, Connect            },
+                { 15, GetPeerName        },
+                { 16, GetSockName        },
+                { 17, GetSockOpt         },
+                { 18, Listen             },
+                { 19, Ioctl              },
+                { 20, Fcntl              },
+                { 21, SetSockOpt         },
+                { 22, Shutdown           },
+                { 23, ShutdownAllSockets },
+                { 24, Write              },
+                { 25, Read               },
+                { 26, Close              },
+                { 27, DuplicateSocket    },
             };
+
+            this.IsPrivileged = IsPrivileged;
         }
 
-        //(u32, u32, u32, u32, u32, u32, u32, u32, u64 pid, u64 transferMemorySize, pid, KObject) -> u32 bsd_errno
-        public long Initialize(ServiceCtx Context)
+        private LinuxError ConvertError(WSAError ErrorCode)
+        {
+            LinuxError Errno;
+
+            if (!ErrorMap.TryGetValue(ErrorCode, out Errno))
+            {
+                Errno = (LinuxError)ErrorCode;
+            }
+
+            return Errno;
+        }
+
+        private long WriteWinSock2Error(ServiceCtx Context, WSAError ErrorCode)
+        {
+            return WriteBsdResult(Context, -1, ConvertError(ErrorCode));
+        }
+
+        private long WriteBsdResult(ServiceCtx Context, int Result, LinuxError ErrorCode = 0)
+        {
+            if (ErrorCode != LinuxError.SUCCESS)
+            {
+                Result = -1;
+            }
+
+            Context.ResponseData.Write(Result);
+            Context.ResponseData.Write((int)ErrorCode);
+
+            return 0;
+        }
+
+        private BsdSocket RetrieveSocket(int SocketFd)
+        {
+            if (SocketFd >= 0 && Sockets.Count > SocketFd)
+            {
+                return Sockets[SocketFd];
+            }
+
+            return null;
+        }
+
+        private LinuxError SetResultErrno(Socket Socket, int Result)
+        {
+            return Result == 0 && !Socket.Blocking ? LinuxError.EWOULDBLOCK : LinuxError.SUCCESS;
+        }
+
+        private AddressFamily ConvertFromBsd(int Domain)
+        {
+            if (Domain == 2)
+            {
+                return AddressFamily.InterNetwork;
+            }
+
+            // FIXME: AF_ROUTE ignored, is that really needed?
+            return AddressFamily.Unknown;
+        }
+
+        private long SocketInternal(ServiceCtx Context, bool Exempt)
+        {
+            AddressFamily Domain   = (AddressFamily)Context.RequestData.ReadInt32();
+            SocketType    Type     = (SocketType)Context.RequestData.ReadInt32();
+            ProtocolType  Protocol = (ProtocolType)Context.RequestData.ReadInt32();
+
+            if (Domain == AddressFamily.Unknown)
+            {
+                return WriteBsdResult(Context, -1, LinuxError.EPROTONOSUPPORT);
+            }
+            else if ((Type == SocketType.Seqpacket || Type == SocketType.Raw) && !IsPrivileged)
+            {
+                if (Domain != AddressFamily.InterNetwork || Type != SocketType.Raw || Protocol != ProtocolType.Icmp)
+                {
+                    return WriteBsdResult(Context, -1, LinuxError.ENOENT);
+                }
+            }
+
+            BsdSocket NewBsdSocket = new BsdSocket
+            {
+                Family   = (int)Domain,
+                Type     = (int)Type,
+                Protocol = (int)Protocol,
+                Handle   = new Socket(Domain, Type, Protocol)
+            };
+
+            Sockets.Add(NewBsdSocket);
+
+            if (Exempt)
+            {
+                NewBsdSocket.Handle.Disconnect(true);
+            }
+
+            return WriteBsdResult(Context, Sockets.Count - 1);
+        }
+
+        private IPEndPoint ParseSockAddr(ServiceCtx Context, long BufferPosition, long BufferSize)
+        {
+            int Size   = Context.Memory.ReadByte(BufferPosition);
+            int Family = Context.Memory.ReadByte(BufferPosition + 1);
+            int Port   = EndianSwap.Swap16(Context.Memory.ReadUInt16(BufferPosition + 2));
+
+            byte[] RawIp = Context.Memory.ReadBytes(BufferPosition + 4, 4);
+
+            return new IPEndPoint(new IPAddress(RawIp), Port);
+        }
+
+        private void WriteSockAddr(ServiceCtx Context, long BufferPosition, IPEndPoint EndPoint)
+        {
+            Context.Memory.WriteByte(BufferPosition, 0);
+            Context.Memory.WriteByte(BufferPosition + 1, (byte)EndPoint.AddressFamily);
+            Context.Memory.WriteUInt16(BufferPosition + 2, EndianSwap.Swap16((ushort)EndPoint.Port));
+            Context.Memory.WriteBytes(BufferPosition + 4, EndPoint.Address.GetAddressBytes());
+        }
+
+        private void WriteSockAddr(ServiceCtx Context, long BufferPosition, BsdSocket Socket, bool IsRemote)
+        {
+            IPEndPoint EndPoint = (IsRemote ? Socket.Handle.RemoteEndPoint : Socket.Handle.LocalEndPoint) as IPEndPoint;
+
+            WriteSockAddr(Context, BufferPosition, EndPoint);
+        }
+
+        // Initialize(nn::socket::BsdBufferConfig config, u64 pid, u64 transferMemorySize, KObject<copy, transfer_memory>, pid) -> u32 bsd_errno
+        public long RegisterClient(ServiceCtx Context)
         {
             /*
             typedef struct  {
@@ -54,447 +274,920 @@ namespace Ryujinx.HLE.HOS.Services.Bsd
             } BsdBufferConfig;
             */
 
+            // bsd_error
             Context.ResponseData.Write(0);
 
-            //Todo: Stub
+            Logger.PrintStub(LogClass.ServiceBsd, "Stubbed.");
 
             return 0;
         }
 
-        //(u64, pid)
+        // StartMonitoring(u64, pid)
         public long StartMonitoring(ServiceCtx Context)
         {
-            //Todo: Stub
+            ulong Unknown0 = Context.RequestData.ReadUInt64();
+
+            Logger.PrintStub(LogClass.ServiceBsd, $"Stubbed. Unknown0: {Unknown0}");
 
             return 0;
         }
 
-        //(u32 domain, u32 type, u32 protocol) -> (i32 ret, u32 bsd_errno)
+        // Socket(u32 domain, u32 type, u32 protocol) -> (i32 ret, u32 bsd_errno)
         public long Socket(ServiceCtx Context)
         {
-            BsdSocket NewBsdSocket = new BsdSocket
-            {
-                Family   = Context.RequestData.ReadInt32(),
-                Type     = Context.RequestData.ReadInt32(),
-                Protocol = Context.RequestData.ReadInt32()
-            };
+            return SocketInternal(Context, false);
+        }
 
-            Sockets.Add(NewBsdSocket);
+        // SocketExempt(u32 domain, u32 type, u32 protocol) -> (i32 ret, u32 bsd_errno)
+        public long SocketExempt(ServiceCtx Context)
+        {
+            return SocketInternal(Context, true);
+        }
 
-            NewBsdSocket.Handle = new Socket((AddressFamily)NewBsdSocket.Family,
-                                                (SocketType)NewBsdSocket.Type,
-                                              (ProtocolType)NewBsdSocket.Protocol);
+        // Open(u32 flags, array<unknown, 0x21> path) -> (i32 ret, u32 bsd_errno)
+        public long Open(ServiceCtx Context)
+        {
+            (long BufferPosition, long BufferSize) = Context.Request.GetBufferType0x21();
 
-            Context.ResponseData.Write(Sockets.Count - 1);
-            Context.ResponseData.Write(0);
+            int Flags = Context.RequestData.ReadInt32();
+
+            byte[] RawPath = Context.Memory.ReadBytes(BufferPosition, BufferSize);
+            string Path    = Encoding.ASCII.GetString(RawPath);
+
+            WriteBsdResult(Context, -1, LinuxError.EOPNOTSUPP);
+
+            Logger.PrintStub(LogClass.ServiceBsd, $"Stubbed. Path: {Path} - " +
+                                                  $"Flags: {Flags}");
 
             return 0;
         }
 
-        //(u32, u32, buffer<unknown, 0x21, 0>) -> (i32 ret, u32 bsd_errno, buffer<unknown, 0x22, 0>)
+        // Select(u32 nfds, nn::socket::timeout timeout, buffer<nn::socket::fd_set, 0x21, 0> readfds_in, buffer<nn::socket::fd_set, 0x21, 0> writefds_in, buffer<nn::socket::fd_set, 0x21, 0> errorfds_in) -> (i32 ret, u32 bsd_errno, buffer<nn::socket::fd_set, 0x22, 0> readfds_out, buffer<nn::socket::fd_set, 0x22, 0> writefds_out, buffer<nn::socket::fd_set, 0x22, 0> errorfds_out)
+        public long Select(ServiceCtx Context)
+        {
+            WriteBsdResult(Context, -1, LinuxError.EOPNOTSUPP);
+
+            Logger.PrintStub(LogClass.ServiceBsd, $"Stubbed.");
+
+            return 0;
+        }
+
+        // Poll(u32 nfds, u32 timeout, buffer<unknown, 0x21, 0> fds) -> (i32 ret, u32 bsd_errno, buffer<unknown, 0x22, 0>)
         public long Poll(ServiceCtx Context)
         {
-            int PollCount = Context.RequestData.ReadInt32();
-            int TimeOut   = Context.RequestData.ReadInt32();
+            int FdsCount = Context.RequestData.ReadInt32();
+            int Timeout  = Context.RequestData.ReadInt32();
 
-            //https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/poll.h
-            //https://msdn.microsoft.com/fr-fr/library/system.net.sockets.socket.poll(v=vs.110).aspx
-            //https://github.com/switchbrew/libnx/blob/e0457c4534b3c37426d83e1a620f82cb28c3b528/nx/source/services/bsd.c#L343
-            //https://github.com/TuxSH/ftpd/blob/switch_pr/source/ftp.c#L1634
-            //https://linux.die.net/man/2/poll
+            (long BufferPosition, long BufferSize) = Context.Request.GetBufferType0x21();
 
-            byte[] SentBuffer = Context.Memory.ReadBytes(Context.Request.SendBuff[0].Position,
-                                                         Context.Request.SendBuff[0].Size);
 
-            int SocketId        = Get32(SentBuffer, 0);
-            int RequestedEvents = Get16(SentBuffer, 4);
-            int ReturnedEvents  = Get16(SentBuffer, 6);
+            if (Timeout < -1 || FdsCount < 0 || (FdsCount * 8) > BufferSize)
+            {
+                return WriteBsdResult(Context, -1, LinuxError.EINVAL);
+            }
 
-            //Todo: Stub - Need to implemented the Type-22 buffer.
+            PollEvent[] Events = new PollEvent[FdsCount];
 
-            Context.ResponseData.Write(1);
-            Context.ResponseData.Write(0);
+            for (int i = 0; i < FdsCount; i++)
+            {
+                int SocketFd = Context.Memory.ReadInt32(BufferPosition + i * 8);
+
+                BsdSocket Socket = RetrieveSocket(SocketFd);
+
+                if (Socket == null)
+                {
+                    return WriteBsdResult(Context, -1, LinuxError.EBADF);
+                }
+
+                PollEvent.EventTypeMask InputEvents  = (PollEvent.EventTypeMask)Context.Memory.ReadInt16(BufferPosition + i * 8 + 4);
+                PollEvent.EventTypeMask OutputEvents = (PollEvent.EventTypeMask)Context.Memory.ReadInt16(BufferPosition + i * 8 + 6);
+
+                Events[i] = new PollEvent(SocketFd, Socket, InputEvents, OutputEvents);
+            }
+
+            List<Socket> ReadEvents  = new List<Socket>();
+            List<Socket> WriteEvents = new List<Socket>();
+            List<Socket> ErrorEvents = new List<Socket>();
+
+            foreach (PollEvent Event in Events)
+            {
+                bool IsValidEvent = false;
+
+                if ((Event.InputEvents & PollEvent.EventTypeMask.Input) != 0)
+                {
+                    ReadEvents.Add(Event.Socket.Handle);
+                    ErrorEvents.Add(Event.Socket.Handle);
+
+                    IsValidEvent = true;
+                }
+
+                if ((Event.InputEvents & PollEvent.EventTypeMask.UrgentInput) != 0)
+                {
+                    ReadEvents.Add(Event.Socket.Handle);
+                    ErrorEvents.Add(Event.Socket.Handle);
+
+                    IsValidEvent = true;
+                }
+
+                if ((Event.InputEvents & PollEvent.EventTypeMask.Output) != 0)
+                {
+                    WriteEvents.Add(Event.Socket.Handle);
+                    ErrorEvents.Add(Event.Socket.Handle);
+
+                    IsValidEvent = true;
+                }
+
+                if ((Event.InputEvents & PollEvent.EventTypeMask.Error) != 0)
+                {
+                    ErrorEvents.Add(Event.Socket.Handle);
+                    IsValidEvent = true;
+                }
+
+                if (!IsValidEvent)
+                {
+                    Logger.PrintWarning(LogClass.ServiceBsd, $"Unsupported Poll input event type: {Event.InputEvents}");
+                    return WriteBsdResult(Context, -1, LinuxError.EINVAL);
+                }
+            }
+
+            try
+            {
+                System.Net.Sockets.Socket.Select(ReadEvents, WriteEvents, ErrorEvents, Timeout);
+            }
+            catch (SocketException Exception)
+            {
+                return WriteWinSock2Error(Context, (WSAError)Exception.ErrorCode);
+            }
+
+            for (int i = 0; i < FdsCount; i++)
+            {
+                PollEvent Event = Events[i];
+                Context.Memory.WriteInt32(BufferPosition + i * 8, Event.SocketFd);
+                Context.Memory.WriteInt16(BufferPosition + i * 8 + 4, (short)Event.InputEvents);
+
+                PollEvent.EventTypeMask OutputEvents = 0;
+
+                Socket Socket = Event.Socket.Handle;
+
+                if (ErrorEvents.Contains(Socket))
+                {
+                    OutputEvents |= PollEvent.EventTypeMask.Error;
+
+                    if (!Socket.Connected || !Socket.IsBound)
+                    {
+                        OutputEvents |= PollEvent.EventTypeMask.Disconnected;
+                    }
+                }
+
+                if (ReadEvents.Contains(Socket))
+                {
+                    if ((Event.InputEvents & PollEvent.EventTypeMask.Input) != 0)
+                    {
+                        OutputEvents |= PollEvent.EventTypeMask.Input;
+                    }
+                }
+
+                if (WriteEvents.Contains(Socket))
+                {
+                    OutputEvents |= PollEvent.EventTypeMask.Output;
+                }
+
+                Context.Memory.WriteInt16(BufferPosition + i * 8 + 6, (short)OutputEvents);
+            }
+
+            return WriteBsdResult(Context, ReadEvents.Count + WriteEvents.Count + ErrorEvents.Count, LinuxError.SUCCESS);
+        }
+
+        // Sysctl(buffer<unknown, 0x21, 0>, buffer<unknown, 0x21, 0>) -> (i32 ret, u32 bsd_errno, u32, buffer<unknown, 0x22, 0>)
+        public long Sysctl(ServiceCtx Context)
+        {
+            WriteBsdResult(Context, -1, LinuxError.EOPNOTSUPP);
+
+            Logger.PrintStub(LogClass.ServiceBsd, $"Stubbed.");
 
             return 0;
         }
 
-        //(u32 socket, u32 flags) -> (i32 ret, u32 bsd_errno, buffer<i8, 0x22, 0> message)
+        // Recv(u32 socket, u32 flags) -> (i32 ret, u32 bsd_errno, array<i8, 0x22> message)
         public long Recv(ServiceCtx Context)
         {
-            int SocketId    = Context.RequestData.ReadInt32();
-            int SocketFlags = Context.RequestData.ReadInt32();
+            int         SocketFd    = Context.RequestData.ReadInt32();
+            SocketFlags SocketFlags = (SocketFlags)Context.RequestData.ReadInt32();
 
             (long ReceivePosition, long ReceiveLength) = Context.Request.GetBufferType0x22();
 
-            byte[] ReceivedBuffer = new byte[ReceiveLength];
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
+            int        Result = -1;
 
-            try
+            if (Socket != null)
             {
-                int BytesRead = Sockets[SocketId].Handle.Receive(ReceivedBuffer);
+                if (SocketFlags != SocketFlags.None && (SocketFlags & SocketFlags.OutOfBand) == 0
+                    && (SocketFlags & SocketFlags.Peek) == 0)
+                {
+                    Logger.PrintWarning(LogClass.ServiceBsd, $"Unsupported Recv flags: {SocketFlags}");
+                    return WriteBsdResult(Context, -1, LinuxError.EOPNOTSUPP);
+                }
 
-                Context.Memory.WriteBytes(ReceivePosition, ReceivedBuffer);
+                byte[] ReceivedBuffer = new byte[ReceiveLength];
 
-                Context.ResponseData.Write(BytesRead);
-                Context.ResponseData.Write(0);
-            }
-            catch (SocketException Ex)
-            {
-                Context.ResponseData.Write(-1);
-                Context.ResponseData.Write(Ex.ErrorCode - 10000);
+                try
+                {
+                    Result = Socket.Handle.Receive(ReceivedBuffer, SocketFlags);
+                    Errno  = SetResultErrno(Socket.Handle, Result);
+
+                    Context.Memory.WriteBytes(ReceivePosition, ReceivedBuffer);
+                }
+                catch (SocketException Exception)
+                {
+                    Errno = ConvertError((WSAError)Exception.ErrorCode);
+                }
             }
 
-            return 0;
+            return WriteBsdResult(Context, Result, Errno);
         }
 
-        //(u32 socket, u32 flags, buffer<i8, 0x21, 0>) -> (i32 ret, u32 bsd_errno)
+        // RecvFrom(u32 sock, u32 flags) -> (i32 ret, u32 bsd_errno, u32 addrlen, buffer<i8, 0x22, 0> message, buffer<nn::socket::sockaddr_in, 0x22, 0x10>)
+        public long RecvFrom(ServiceCtx Context)
+        {
+            int         SocketFd    = Context.RequestData.ReadInt32();
+            SocketFlags SocketFlags = (SocketFlags)Context.RequestData.ReadInt32();
+
+            (long ReceivePosition,     long ReceiveLength)   = Context.Request.GetBufferType0x22();
+            (long SockAddrInPosition,  long SockAddrInSize)  = Context.Request.GetBufferType0x21();
+            (long SockAddrOutPosition, long SockAddrOutSize) = Context.Request.GetBufferType0x22(1);
+
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
+            int        Result = -1;
+
+            if (Socket != null)
+            {
+                if (SocketFlags != SocketFlags.None && (SocketFlags & SocketFlags.OutOfBand) == 0
+                    && (SocketFlags & SocketFlags.Peek) == 0)
+                {
+                    Logger.PrintWarning(LogClass.ServiceBsd, $"Unsupported Recv flags: {SocketFlags}");
+
+                    return WriteBsdResult(Context, -1, LinuxError.EOPNOTSUPP);
+                }
+
+                byte[]   ReceivedBuffer = new byte[ReceiveLength];
+                EndPoint EndPoint       = ParseSockAddr(Context, SockAddrInPosition, SockAddrInSize);
+
+                try
+                {
+                    Result = Socket.Handle.ReceiveFrom(ReceivedBuffer, ReceivedBuffer.Length, SocketFlags, ref EndPoint);
+                    Errno  = SetResultErrno(Socket.Handle, Result);
+
+                    Context.Memory.WriteBytes(ReceivePosition, ReceivedBuffer);
+                    WriteSockAddr(Context, SockAddrOutPosition, (IPEndPoint)EndPoint);
+                }
+                catch (SocketException Exception)
+                {
+                    Errno = ConvertError((WSAError)Exception.ErrorCode);
+                }
+            }
+
+            return WriteBsdResult(Context, Result, Errno);
+        }
+
+        // Send(u32 socket, u32 flags, buffer<i8, 0x21, 0>) -> (i32 ret, u32 bsd_errno)
         public long Send(ServiceCtx Context)
         {
-            int SocketId    = Context.RequestData.ReadInt32();
-            int SocketFlags = Context.RequestData.ReadInt32();
+            int         SocketFd    = Context.RequestData.ReadInt32();
+            SocketFlags SocketFlags = (SocketFlags)Context.RequestData.ReadInt32();
 
-            (long SentPosition, long SentSize) = Context.Request.GetBufferType0x21();
+            (long SendPosition, long SendSize) = Context.Request.GetBufferType0x21();
 
-            byte[] SentBuffer = Context.Memory.ReadBytes(SentPosition, SentSize);
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
+            int        Result = -1;
 
-            try
+            if (Socket != null)
             {
-                int BytesSent = Sockets[SocketId].Handle.Send(SentBuffer);
+                if (SocketFlags != SocketFlags.None && SocketFlags != SocketFlags.OutOfBand
+                    && SocketFlags != SocketFlags.Peek && SocketFlags != SocketFlags.DontRoute)
+                {
+                    Logger.PrintWarning(LogClass.ServiceBsd, $"Unsupported Send flags: {SocketFlags}");
+
+                    return WriteBsdResult(Context, -1, LinuxError.EOPNOTSUPP);
+                }
+
+                byte[] SendBuffer = Context.Memory.ReadBytes(SendPosition, SendSize);
+
+                try
+                {
+                    Result = Socket.Handle.Send(SendBuffer, SocketFlags);
+                    Errno  = SetResultErrno(Socket.Handle, Result);
+                }
+                catch (SocketException Exception)
+                {
+                    Errno = ConvertError((WSAError)Exception.ErrorCode);
+                }
 
-                Context.ResponseData.Write(BytesSent);
-                Context.ResponseData.Write(0);
-            }
-            catch (SocketException Ex)
-            {
-                Context.ResponseData.Write(-1);
-                Context.ResponseData.Write(Ex.ErrorCode - 10000);
             }
 
-            return 0;
+            return WriteBsdResult(Context, Result, Errno);
         }
 
-        //(u32 socket, u32 flags, buffer<i8, 0x21, 0>, buffer<sockaddr, 0x21, 0>) -> (i32 ret, u32 bsd_errno)
+        // SendTo(u32 socket, u32 flags, buffer<i8, 0x21, 0>, buffer<nn::socket::sockaddr_in, 0x21, 0x10>) -> (i32 ret, u32 bsd_errno)
         public long SendTo(ServiceCtx Context)
         {
-            int SocketId    = Context.RequestData.ReadInt32();
-            int SocketFlags = Context.RequestData.ReadInt32();
+            int         SocketFd    = Context.RequestData.ReadInt32();
+            SocketFlags SocketFlags = (SocketFlags)Context.RequestData.ReadInt32();
 
-            byte[] SentBuffer = Context.Memory.ReadBytes(Context.Request.SendBuff[0].Position,
-                                                         Context.Request.SendBuff[0].Size);
+            (long SendPosition,   long SendSize)   = Context.Request.GetBufferType0x21();
+            (long BufferPosition, long BufferSize) = Context.Request.GetBufferType0x21(1);
 
-            (long AddressPosition, long AddressSize) = Context.Request.GetBufferType0x21(Index: 1);
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
+            int        Result = -1;
 
-            byte[] AddressBuffer = Context.Memory.ReadBytes(AddressPosition, AddressSize);
-
-            if (!Sockets[SocketId].Handle.Connected)
+            if (Socket != null)
             {
+                if (SocketFlags != SocketFlags.None && SocketFlags != SocketFlags.OutOfBand
+                    && SocketFlags != SocketFlags.Peek && SocketFlags != SocketFlags.DontRoute)
+                {
+                    Logger.PrintWarning(LogClass.ServiceBsd, $"Unsupported Send flags: {SocketFlags}");
+
+                    return WriteBsdResult(Context, -1, LinuxError.EOPNOTSUPP);
+                }
+
+                byte[]   SendBuffer = Context.Memory.ReadBytes(SendPosition, SendSize);
+                EndPoint EndPoint   = ParseSockAddr(Context, BufferPosition, BufferSize);
+
                 try
                 {
-                    ParseAddrBuffer(SocketId, AddressBuffer);
-
-                    Sockets[SocketId].Handle.Connect(Sockets[SocketId].RemoteEP);
+                    Result = Socket.Handle.SendTo(SendBuffer, SendBuffer.Length, SocketFlags, EndPoint);
+                    Errno  = SetResultErrno(Socket.Handle, Result);
                 }
-                catch (SocketException Ex)
+                catch (SocketException Exception)
                 {
-                    Context.ResponseData.Write(-1);
-                    Context.ResponseData.Write(Ex.ErrorCode - 10000);
+                    Errno = ConvertError((WSAError)Exception.ErrorCode);
                 }
+
             }
 
-            try
-            {
-                int BytesSent = Sockets[SocketId].Handle.Send(SentBuffer);
-
-                Context.ResponseData.Write(BytesSent);
-                Context.ResponseData.Write(0);
-            }
-            catch (SocketException Ex)
-            {
-                Context.ResponseData.Write(-1);
-                Context.ResponseData.Write(Ex.ErrorCode - 10000);
-            }
-
-            return 0;
+            return WriteBsdResult(Context, Result, Errno);
         }
 
-        //(u32 socket) -> (i32 ret, u32 bsd_errno, u32 addrlen, buffer<sockaddr, 0x22, 0> addr)
+        // Accept(u32 socket) -> (i32 ret, u32 bsd_errno, u32 addrlen, buffer<nn::socket::sockaddr_in, 0x22, 0x10> addr)
         public long Accept(ServiceCtx Context)
         {
-            int SocketId = Context.RequestData.ReadInt32();
+            int SocketFd = Context.RequestData.ReadInt32();
 
-            (long AddrBufferPosition, long AddrBuffSize) = Context.Request.GetBufferType0x22();
+            (long BufferPos, long BufferSize) = Context.Request.GetBufferType0x22();
 
-            Socket HandleAccept = null;
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
 
-            Task TimeOut = Task.Factory.StartNew(() =>
+            if (Socket != null)
             {
+                Errno = LinuxError.SUCCESS;
+
+                Socket NewSocket = null;
+
                 try
                 {
-                    HandleAccept = Sockets[SocketId].Handle.Accept();
+                    NewSocket = Socket.Handle.Accept();
                 }
-                catch (SocketException Ex)
+                catch (SocketException Exception)
                 {
-                    Context.ResponseData.Write(-1);
-                    Context.ResponseData.Write(Ex.ErrorCode - 10000);
+                    Errno = ConvertError((WSAError)Exception.ErrorCode);
                 }
-            });
 
-            TimeOut.Wait(10000);
-
-            if (HandleAccept != null)
-            {
-                BsdSocket NewBsdSocket = new BsdSocket
+                if (NewSocket == null && Errno == LinuxError.SUCCESS)
                 {
-                    IpAddress = ((IPEndPoint)Sockets[SocketId].Handle.LocalEndPoint).Address,
-                    RemoteEP  = ((IPEndPoint)Sockets[SocketId].Handle.LocalEndPoint),
-                    Handle = HandleAccept
-                };
-
-                Sockets.Add(NewBsdSocket);
-
-                using (MemoryStream MS = new MemoryStream())
+                    Errno = LinuxError.EWOULDBLOCK;
+                }
+                else if (Errno == LinuxError.SUCCESS)
                 {
-                    BinaryWriter Writer = new BinaryWriter(MS);
+                    BsdSocket NewBsdSocket = new BsdSocket
+                    {
+                        Family   = (int)NewSocket.AddressFamily,
+                        Type     = (int)NewSocket.SocketType,
+                        Protocol = (int)NewSocket.ProtocolType,
+                        Handle   = NewSocket,
+                    };
 
-                    Writer.Write((byte)0);
+                    Sockets.Add(NewBsdSocket);
 
-                    Writer.Write((byte)NewBsdSocket.Handle.AddressFamily);
+                    WriteSockAddr(Context, BufferPos, NewBsdSocket, true);
 
-                    Writer.Write((short)((IPEndPoint)NewBsdSocket.Handle.LocalEndPoint).Port);
+                    WriteBsdResult(Context, Sockets.Count - 1, Errno);
 
-                    byte[] IpAddress = NewBsdSocket.IpAddress.GetAddressBytes();
+                    Context.ResponseData.Write(0x10);
 
-                    Writer.Write(IpAddress);
-
-                    Context.Memory.WriteBytes(AddrBufferPosition, MS.ToArray());
-
-                    Context.ResponseData.Write(Sockets.Count - 1);
-                    Context.ResponseData.Write(0);
-                    Context.ResponseData.Write(MS.Length);
+                    return 0;
                 }
             }
-            else
-            {
-                Context.ResponseData.Write(-1);
-                Context.ResponseData.Write((int)BsdError.Timeout);
-            }
 
-            return 0;
+            return WriteBsdResult(Context, -1, Errno);
         }
 
-        //(u32 socket, buffer<sockaddr, 0x21, 0>) -> (i32 ret, u32 bsd_errno)
+        // Bind(u32 socket, buffer<nn::socket::sockaddr_in, 0x21, 0x10> addr) -> (i32 ret, u32 bsd_errno)
         public long Bind(ServiceCtx Context)
         {
-            int SocketId = Context.RequestData.ReadInt32();
+            int SocketFd = Context.RequestData.ReadInt32();
 
-            (long AddressPosition, long AddressSize) = Context.Request.GetBufferType0x21();
+            (long BufferPos, long BufferSize) = Context.Request.GetBufferType0x21();
 
-            byte[] AddressBuffer = Context.Memory.ReadBytes(AddressPosition, AddressSize);
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
 
-            try
+            if (Socket != null)
             {
-                ParseAddrBuffer(SocketId, AddressBuffer);
+                Errno = LinuxError.SUCCESS;
 
-                Context.ResponseData.Write(0);
-                Context.ResponseData.Write(0);
-            }
-            catch (SocketException Ex)
-            {
-                Context.ResponseData.Write(-1);
-                Context.ResponseData.Write(Ex.ErrorCode - 10000);
+                try
+                {
+                    IPEndPoint EndPoint = ParseSockAddr(Context, BufferPos, BufferSize);
+
+                    Socket.Handle.Bind(EndPoint);
+                }
+                catch (SocketException Exception)
+                {
+                    Errno = ConvertError((WSAError)Exception.ErrorCode);
+                }
             }
 
-            return 0;
+            return WriteBsdResult(Context, 0, Errno);
         }
 
-        //(u32 socket, buffer<sockaddr, 0x21, 0>) -> (i32 ret, u32 bsd_errno)
+        // Connect(u32 socket, buffer<nn::socket::sockaddr_in, 0x21, 0x10>) -> (i32 ret, u32 bsd_errno)
         public long Connect(ServiceCtx Context)
         {
-            int SocketId = Context.RequestData.ReadInt32();
+            int SocketFd = Context.RequestData.ReadInt32();
 
-            (long AddressPosition, long AddressSize) = Context.Request.GetBufferType0x21();
+            (long BufferPos, long BufferSize) = Context.Request.GetBufferType0x21();
 
-            byte[] AddressBuffer = Context.Memory.ReadBytes(AddressPosition, AddressSize);
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
 
-            try
+            if (Socket != null)
             {
-                ParseAddrBuffer(SocketId, AddressBuffer);
+                Errno = LinuxError.SUCCESS;
+                try
+                {
+                    IPEndPoint EndPoint = ParseSockAddr(Context, BufferPos, BufferSize);
 
-                Sockets[SocketId].Handle.Connect(Sockets[SocketId].RemoteEP);
-
-                Context.ResponseData.Write(0);
-                Context.ResponseData.Write(0);
-            }
-            catch (SocketException Ex)
-            {
-                Context.ResponseData.Write(-1);
-                Context.ResponseData.Write(Ex.ErrorCode - 10000);
+                    Socket.Handle.Connect(EndPoint);
+                }
+                catch (SocketException Exception)
+                {
+                    Errno = ConvertError((WSAError)Exception.ErrorCode);
+                }
             }
 
-            return 0;
+            return WriteBsdResult(Context, 0, Errno);
         }
 
-        //(u32 socket, u32 backlog) -> (i32 ret, u32 bsd_errno)
+        // GetPeerName(u32 socket) -> (i32 ret, u32 bsd_errno, u32 addrlen, buffer<nn::socket::sockaddr_in, 0x22, 0x10> addr)
+        public long GetPeerName(ServiceCtx Context)
+        {
+            int SocketFd = Context.RequestData.ReadInt32();
+
+            (long BufferPos, long BufferSize) = Context.Request.GetBufferType0x22();
+
+            LinuxError  Errno  = LinuxError.EBADF;
+            BsdSocket Socket = RetrieveSocket(SocketFd);
+
+            if (Socket != null)
+            {
+                Errno = LinuxError.SUCCESS;
+
+                WriteSockAddr(Context, BufferPos, Socket, true);
+                WriteBsdResult(Context, 0, Errno);
+                Context.ResponseData.Write(0x10);
+            }
+
+            return WriteBsdResult(Context, 0, Errno);
+        }
+
+        // GetSockName(u32 socket) -> (i32 ret, u32 bsd_errno, u32 addrlen, buffer<nn::socket::sockaddr_in, 0x22, 0x10> addr)
+        public long GetSockName(ServiceCtx Context)
+        {
+            int SocketFd = Context.RequestData.ReadInt32();
+
+            (long BufferPos, long BufferSize) = Context.Request.GetBufferType0x22();
+
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
+
+            if (Socket != null)
+            {
+                Errno = LinuxError.SUCCESS;
+
+                WriteSockAddr(Context, BufferPos, Socket, false);
+                WriteBsdResult(Context, 0, Errno);
+                Context.ResponseData.Write(0x10);
+            }
+
+            return WriteBsdResult(Context, 0, Errno);
+        }
+
+        // GetSockOpt(u32 socket, u32 level, u32 option_name) -> (i32 ret, u32 bsd_errno, u32, buffer<unknown, 0x22, 0>)
+        public long GetSockOpt(ServiceCtx Context)
+        {
+            int SocketFd   = Context.RequestData.ReadInt32();
+            int Level      = Context.RequestData.ReadInt32();
+            int OptionName = Context.RequestData.ReadInt32();
+
+            (long BufferPosition, long BufferSize) = Context.Request.GetBufferType0x22();
+
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
+
+            if (Socket != null)
+            {
+                Errno = LinuxError.ENOPROTOOPT;
+
+                if (Level == 0xFFFF)
+                {
+                    Errno = HandleGetSocketOption(Context, Socket, (SocketOptionName)OptionName, BufferPosition, BufferSize);
+                }
+                else
+                {
+                    Logger.PrintWarning(LogClass.ServiceBsd, $"Unsupported GetSockOpt Level: {(SocketOptionLevel)Level}");
+                }
+            }
+
+            return WriteBsdResult(Context, 0, Errno);
+        }
+
+        // Listen(u32 socket, u32 backlog) -> (i32 ret, u32 bsd_errno)
         public long Listen(ServiceCtx Context)
         {
-            int SocketId = Context.RequestData.ReadInt32();
-            int BackLog  = Context.RequestData.ReadInt32();
+            int SocketFd = Context.RequestData.ReadInt32();
+            int Backlog  = Context.RequestData.ReadInt32();
 
-            try
-            {
-                Sockets[SocketId].Handle.Bind(Sockets[SocketId].RemoteEP);
-                Sockets[SocketId].Handle.Listen(BackLog);
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
 
-                Context.ResponseData.Write(0);
-                Context.ResponseData.Write(0);
-            }
-            catch (SocketException Ex)
+            if (Socket != null)
             {
-                Context.ResponseData.Write(-1);
-                Context.ResponseData.Write(Ex.ErrorCode - 10000);
+                Errno = LinuxError.SUCCESS;
+
+                try
+                {
+                    Socket.Handle.Listen(Backlog);
+                }
+                catch (SocketException Exception)
+                {
+                    Errno = ConvertError((WSAError)Exception.ErrorCode);
+                }
             }
 
-            return 0;
+            return WriteBsdResult(Context, 0, Errno);
         }
 
-        //(u32 socket, u32 level, u32 option_name, buffer<unknown, 0x21, 0>) -> (i32 ret, u32 bsd_errno)
+        // Ioctl(u32 fd, u32 request, u32 bufcount, buffer<unknown, 0x21, 0>, buffer<unknown, 0x21, 0>, buffer<unknown, 0x21, 0>, buffer<unknown, 0x21, 0>) -> (i32 ret, u32 bsd_errno, buffer<unknown, 0x22, 0>, buffer<unknown, 0x22, 0>, buffer<unknown, 0x22, 0>, buffer<unknown, 0x22, 0>)
+        public long Ioctl(ServiceCtx Context)
+        {
+            int      SocketFd    = Context.RequestData.ReadInt32();
+            BsdIoctl Cmd         = (BsdIoctl)Context.RequestData.ReadInt32();
+            int      BufferCount = Context.RequestData.ReadInt32();
+
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
+
+            if (Socket != null)
+            {
+                switch (Cmd)
+                {
+                    case BsdIoctl.AtMark:
+                        Errno = LinuxError.SUCCESS;
+
+                        (long BufferPosition, long BufferSize) = Context.Request.GetBufferType0x22();
+
+                        // FIXME: OOB not implemented.
+                        Context.Memory.WriteInt32(BufferPosition, 0);
+                        break;
+
+                    default:
+                        Errno = LinuxError.EOPNOTSUPP;
+
+                        Logger.PrintWarning(LogClass.ServiceBsd, $"Unsupported Ioctl Cmd: {Cmd}");
+                        break;
+                }
+            }
+
+            return WriteBsdResult(Context, 0, Errno);
+        }
+
+        // Fcntl(u32 socket, u32 cmd, u32 arg) -> (i32 ret, u32 bsd_errno)
+        public long Fcntl(ServiceCtx Context)
+        {
+            int SocketFd = Context.RequestData.ReadInt32();
+            int Cmd      = Context.RequestData.ReadInt32();
+            int Arg      = Context.RequestData.ReadInt32();
+
+            int        Result = 0;
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
+
+            if (Socket != null)
+            {
+                Errno = LinuxError.SUCCESS;
+
+                if (Cmd == 0x3)
+                {
+                    Result = !Socket.Handle.Blocking ? 0x800 : 0;
+                }
+                else if (Cmd == 0x4 && Arg == 0x800)
+                {
+                    Socket.Handle.Blocking = false;
+                    Result = 0;
+                }
+                else
+                {
+                    Errno = LinuxError.EOPNOTSUPP;
+                }
+            }
+
+            return WriteBsdResult(Context, Result, Errno);
+        }
+
+        private LinuxError HandleGetSocketOption(ServiceCtx Context, BsdSocket Socket, SocketOptionName OptionName, long OptionValuePosition, long OptionValueSize)
+        {
+            try
+            {
+                byte[] OptionValue = new byte[OptionValueSize];
+
+                switch (OptionName)
+                {
+                    case SocketOptionName.Broadcast:
+                    case SocketOptionName.DontLinger:
+                    case SocketOptionName.Debug:
+                    case SocketOptionName.Error:
+                    case SocketOptionName.KeepAlive:
+                    case SocketOptionName.OutOfBandInline:
+                    case SocketOptionName.ReceiveBuffer:
+                    case SocketOptionName.ReceiveTimeout:
+                    case SocketOptionName.SendBuffer:
+                    case SocketOptionName.SendTimeout:
+                    case SocketOptionName.Type:
+                    case SocketOptionName.Linger:
+                        Socket.Handle.GetSocketOption(SocketOptionLevel.Socket, OptionName, OptionValue);
+                        Context.Memory.WriteBytes(OptionValuePosition, OptionValue);
+
+                        return LinuxError.SUCCESS;
+
+                    case (SocketOptionName)0x200:
+                        Socket.Handle.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, OptionValue);
+                        Context.Memory.WriteBytes(OptionValuePosition, OptionValue);
+
+                        return LinuxError.SUCCESS;
+
+                    default:
+                        Logger.PrintWarning(LogClass.ServiceBsd, $"Unsupported SetSockOpt OptionName: {OptionName}");
+
+                        return LinuxError.EOPNOTSUPP;
+                }
+            }
+            catch (SocketException Exception)
+            {
+                return ConvertError((WSAError)Exception.ErrorCode);
+            }
+        }
+
+        private LinuxError HandleSetSocketOption(ServiceCtx Context, BsdSocket Socket, SocketOptionName OptionName, long OptionValuePosition, long OptionValueSize)
+        {
+            try
+            {
+                switch (OptionName)
+                {
+                    case SocketOptionName.Broadcast:
+                    case SocketOptionName.DontLinger:
+                    case SocketOptionName.Debug:
+                    case SocketOptionName.Error:
+                    case SocketOptionName.KeepAlive:
+                    case SocketOptionName.OutOfBandInline:
+                    case SocketOptionName.ReceiveBuffer:
+                    case SocketOptionName.ReceiveTimeout:
+                    case SocketOptionName.SendBuffer:
+                    case SocketOptionName.SendTimeout:
+                    case SocketOptionName.Type:
+                    case SocketOptionName.ReuseAddress:
+                        Socket.Handle.SetSocketOption(SocketOptionLevel.Socket, OptionName, Context.Memory.ReadInt32(OptionValuePosition));
+
+                        return LinuxError.SUCCESS;
+
+                    case (SocketOptionName)0x200:
+                        Socket.Handle.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, Context.Memory.ReadInt32(OptionValuePosition));
+
+                        return LinuxError.SUCCESS;
+
+                    case SocketOptionName.Linger:
+                        Socket.Handle.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger,
+                            new LingerOption(Context.Memory.ReadInt32(OptionValuePosition) != 0, Context.Memory.ReadInt32(OptionValuePosition + 4)));
+
+                        return LinuxError.SUCCESS;
+
+                    default:
+                        Logger.PrintWarning(LogClass.ServiceBsd, $"Unsupported SetSockOpt OptionName: {OptionName}");
+
+                        return LinuxError.EOPNOTSUPP;
+                }
+            }
+            catch (SocketException Exception)
+            {
+                return ConvertError((WSAError)Exception.ErrorCode);
+            }
+        }
+
+        // SetSockOpt(u32 socket, u32 level, u32 option_name, buffer<unknown, 0x21, 0> option_value) -> (i32 ret, u32 bsd_errno)
         public long SetSockOpt(ServiceCtx Context)
         {
-            int SocketId = Context.RequestData.ReadInt32();
+            int SocketFd   = Context.RequestData.ReadInt32();
+            int Level      = Context.RequestData.ReadInt32();
+            int OptionName = Context.RequestData.ReadInt32();
 
-            SocketOptionLevel SocketLevel     = (SocketOptionLevel)Context.RequestData.ReadInt32();
-            SocketOptionName SocketOptionName = (SocketOptionName)Context.RequestData.ReadInt32();
+            (long BufferPos, long BufferSize) = Context.Request.GetBufferType0x21();
 
-            byte[] SocketOptionValue = Context.Memory.ReadBytes(Context.Request.PtrBuff[0].Position,
-                                                                Context.Request.PtrBuff[0].Size);
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
 
-            int OptionValue = Get32(SocketOptionValue, 0);
-
-            try
+            if (Socket != null)
             {
-                Sockets[SocketId].Handle.SetSocketOption(SocketLevel, SocketOptionName, OptionValue);
+                Errno = LinuxError.ENOPROTOOPT;
 
-                Context.ResponseData.Write(0);
-                Context.ResponseData.Write(0);
-            }
-            catch (SocketException Ex)
-            {
-                Context.ResponseData.Write(-1);
-                Context.ResponseData.Write(Ex.ErrorCode - 10000);
+                if (Level == 0xFFFF)
+                {
+                    Errno = HandleSetSocketOption(Context, Socket, (SocketOptionName)OptionName, BufferPos, BufferSize);
+                }
+                else
+                {
+                    Logger.PrintWarning(LogClass.ServiceBsd, $"Unsupported SetSockOpt Level: {(SocketOptionLevel)Level}");
+                }
             }
 
-            return 0;
+            return WriteBsdResult(Context, 0, Errno);
         }
 
-        //(u32 socket, buffer<i8, 0x21, 0> message) -> (i32 ret, u32 bsd_errno)
+        // Shutdown(u32 socket, u32 how) -> (i32 ret, u32 bsd_errno)
+        public long Shutdown(ServiceCtx Context)
+        {
+            int SocketFd = Context.RequestData.ReadInt32();
+            int How      = Context.RequestData.ReadInt32();
+
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
+
+            if (Socket != null)
+            {
+                Errno = LinuxError.EINVAL;
+
+                if (How >= 0 && How <= 2)
+                {
+                    Errno = LinuxError.SUCCESS;
+
+                    try
+                    {
+                        Socket.Handle.Shutdown((SocketShutdown)How);
+                    }
+                    catch (SocketException Exception)
+                    {
+                        Errno = ConvertError((WSAError)Exception.ErrorCode);
+                    }
+                }
+            }
+
+            return WriteBsdResult(Context, 0, Errno);
+        }
+
+        // ShutdownAllSockets(u32 how) -> (i32 ret, u32 bsd_errno)
+        public long ShutdownAllSockets(ServiceCtx Context)
+        {
+            int How = Context.RequestData.ReadInt32();
+
+            LinuxError Errno = LinuxError.EINVAL;
+
+            if (How >= 0 && How <= 2)
+            {
+                Errno = LinuxError.SUCCESS;
+
+                foreach (BsdSocket Socket in Sockets)
+                {
+                    if (Socket != null)
+                    {
+                        try
+                        {
+                            Socket.Handle.Shutdown((SocketShutdown)How);
+                        }
+                        catch (SocketException Exception)
+                        {
+                            Errno = ConvertError((WSAError)Exception.ErrorCode);
+                            break;
+                        }
+                    }
+                }
+            }
+
+            return WriteBsdResult(Context, 0, Errno);
+        }
+
+        // Write(u32 socket, buffer<i8, 0x21, 0> message) -> (i32 ret, u32 bsd_errno)
         public long Write(ServiceCtx Context)
         {
-            int SocketId = Context.RequestData.ReadInt32();
+            int SocketFd = Context.RequestData.ReadInt32();
 
-            (long SentPosition, long SentSize) = Context.Request.GetBufferType0x21();
+            (long SendPosition, long SendSize) = Context.Request.GetBufferType0x21();
 
-            byte[] SentBuffer = Context.Memory.ReadBytes(SentPosition, SentSize);
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
+            int        Result = -1;
 
-            try
+            if (Socket != null)
             {
-                //Logging.Debug("Wrote Buffer:" + Environment.NewLine + Logging.HexDump(SentBuffer));
+                byte[] SendBuffer = Context.Memory.ReadBytes(SendPosition, SendSize);
 
-                int BytesSent = Sockets[SocketId].Handle.Send(SentBuffer);
-
-                Context.ResponseData.Write(BytesSent);
-                Context.ResponseData.Write(0);
-            }
-            catch (SocketException Ex)
-            {
-                Context.ResponseData.Write(-1);
-                Context.ResponseData.Write(Ex.ErrorCode - 10000);
+                try
+                {
+                    Result = Socket.Handle.Send(SendBuffer);
+                    Errno  = SetResultErrno(Socket.Handle, Result);
+                }
+                catch (SocketException Exception)
+                {
+                    Errno = ConvertError((WSAError)Exception.ErrorCode);
+                }
             }
 
-            return 0;
+            return WriteBsdResult(Context, Result, Errno);
         }
 
-        //(u32 socket) -> (i32 ret, u32 bsd_errno, buffer<i8, 0x22, 0> message)
+        // Read(u32 socket) -> (i32 ret, u32 bsd_errno, buffer<i8, 0x22, 0> message)
         public long Read(ServiceCtx Context)
         {
-            int SocketId = Context.RequestData.ReadInt32();
+            int SocketFd = Context.RequestData.ReadInt32();
 
             (long ReceivePosition, long ReceiveLength) = Context.Request.GetBufferType0x22();
 
-            byte[] ReceivedBuffer = new byte[ReceiveLength];
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
+            int        Result = -1;
 
-            try
+            if (Socket != null)
             {
-                int BytesRead = Sockets[SocketId].Handle.Receive(ReceivedBuffer);
+                byte[] ReceivedBuffer = new byte[ReceiveLength];
 
-                Context.Memory.WriteBytes(ReceivePosition, ReceivedBuffer);
-
-                Context.ResponseData.Write(BytesRead);
-                Context.ResponseData.Write(0);
-            }
-            catch (SocketException Ex)
-            {
-                Context.ResponseData.Write(-1);
-                Context.ResponseData.Write(Ex.ErrorCode - 10000);
+                try
+                {
+                    Result = Socket.Handle.Receive(ReceivedBuffer);
+                    Errno  = SetResultErrno(Socket.Handle, Result);
+                }
+                catch (SocketException Exception)
+                {
+                    Errno = ConvertError((WSAError)Exception.ErrorCode);
+                }
             }
 
-            return 0;
+            return WriteBsdResult(Context, Result, Errno);
         }
 
-        //(u32 socket) -> (i32 ret, u32 bsd_errno)
+        // Close(u32 socket) -> (i32 ret, u32 bsd_errno)
         public long Close(ServiceCtx Context)
         {
-            int SocketId = Context.RequestData.ReadInt32();
+            int SocketFd = Context.RequestData.ReadInt32();
 
-            try
-            {
-                Sockets[SocketId].Handle.Close();
-                Sockets[SocketId] = null;
+            LinuxError Errno  = LinuxError.EBADF;
+            BsdSocket  Socket = RetrieveSocket(SocketFd);
 
-                Context.ResponseData.Write(0);
-                Context.ResponseData.Write(0);
-            }
-            catch (SocketException Ex)
+            if (Socket != null)
             {
-                Context.ResponseData.Write(-1);
-                Context.ResponseData.Write(Ex.ErrorCode - 10000);
+                Socket.Handle.Close();
+
+                Sockets[SocketFd] = null;
+
+                Errno = LinuxError.SUCCESS;
             }
 
-            return 0;
+            return WriteBsdResult(Context, 0, Errno);
         }
 
-        public void ParseAddrBuffer(int SocketId, byte[] AddrBuffer)
+        // DuplicateSocket(u32 socket, u64 reserved) -> (i32 ret, u32 bsd_errno)
+        public long DuplicateSocket(ServiceCtx Context)
         {
-            using (MemoryStream MS = new MemoryStream(AddrBuffer))
+            int   SocketFd = Context.RequestData.ReadInt32();
+            ulong Reserved = Context.RequestData.ReadUInt64();
+
+            LinuxError Errno     = LinuxError.ENOENT;
+            int        NewSockFd = -1;
+
+            if (IsPrivileged)
             {
-                BinaryReader Reader = new BinaryReader(MS);
+                Errno = LinuxError.EBADF;
 
-                int Size   = Reader.ReadByte();
-                int Family = Reader.ReadByte();
-                int Port   = EndianSwap.Swap16(Reader.ReadUInt16());
+                BsdSocket OldSocket = RetrieveSocket(SocketFd);
 
-                string IpAddress = Reader.ReadByte().ToString() + "." +
-                                   Reader.ReadByte().ToString() + "." +
-                                   Reader.ReadByte().ToString() + "." +
-                                   Reader.ReadByte().ToString();
-
-                Sockets[SocketId].IpAddress = IPAddress.Parse(IpAddress);
-                Sockets[SocketId].RemoteEP  = new IPEndPoint(Sockets[SocketId].IpAddress, Port);
+                if (OldSocket != null)
+                {
+                    Sockets.Add(OldSocket);
+                    NewSockFd = Sockets.Count - 1;
+                }
             }
-        }
 
-        private int Get16(byte[] Data, int Address)
-        {
-            return
-                Data[Address + 0] << 0 |
-                Data[Address + 1] << 8;
-        }
-
-        private int Get32(byte[] Data, int Address)
-        {
-            return
-                Data[Address + 0] << 0 |
-                Data[Address + 1] << 8 |
-                Data[Address + 2] << 16 |
-                Data[Address + 3] << 24;
+            return WriteBsdResult(Context, NewSockFd, Errno);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/Ryujinx.HLE/HOS/Services/Bsd/PollEvent.cs b/Ryujinx.HLE/HOS/Services/Bsd/PollEvent.cs
new file mode 100644
index 0000000000..49cd4877ee
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Bsd/PollEvent.cs
@@ -0,0 +1,28 @@
+namespace Ryujinx.HLE.HOS.Services.Bsd
+{
+    class PollEvent
+    {
+        public enum EventTypeMask
+        {
+            Input        = 1,
+            UrgentInput  = 2,
+            Output       = 4,
+            Error        = 8,
+            Disconnected = 0x10,
+            Invalid      = 0x20,
+        }
+
+        public int           SocketFd     { get; private set; }
+        public BsdSocket     Socket       { get; private set; }
+        public EventTypeMask InputEvents  { get; private set; }
+        public EventTypeMask OutputEvents { get; private set; }
+
+        public PollEvent(int SocketFd, BsdSocket Socket, EventTypeMask InputEvents, EventTypeMask OutputEvents)
+        {
+            this.SocketFd     = SocketFd;
+            this.Socket       = Socket;
+            this.InputEvents  = InputEvents;
+            this.OutputEvents = OutputEvents;
+        }
+    }
+}
diff --git a/Ryujinx.HLE/HOS/Services/ServiceFactory.cs b/Ryujinx.HLE/HOS/Services/ServiceFactory.cs
index f701dd0537..29f1c0e775 100644
--- a/Ryujinx.HLE/HOS/Services/ServiceFactory.cs
+++ b/Ryujinx.HLE/HOS/Services/ServiceFactory.cs
@@ -72,10 +72,10 @@ namespace Ryujinx.HLE.HOS.Services
                     return new Bcat.IServiceCreator();
 
                 case "bsd:s":
-                    return new IClient();
+                    return new IClient(true);
 
                 case "bsd:u":
-                    return new IClient();
+                    return new IClient(false);
 
                 case "caps:a":
                     return new IAlbumAccessorService();
diff --git a/Ryujinx.HLE/Utilities/LinuxError.cs b/Ryujinx.HLE/Utilities/LinuxError.cs
new file mode 100644
index 0000000000..5c322f83cf
--- /dev/null
+++ b/Ryujinx.HLE/Utilities/LinuxError.cs
@@ -0,0 +1,152 @@
+namespace Ryujinx.HLE.Utilities
+{
+    enum LinuxError
+    {
+        SUCCESS         = 0,
+        EPERM           = 1       /* Operation not permitted */,
+        ENOENT          = 2       /* No such file or directory */,
+        ESRCH           = 3       /* No such process */,
+        EINTR           = 4       /* Interrupted system call */,
+        EIO             = 5       /* I/O error */,
+        ENXIO           = 6       /* No such device or address */,
+        E2BIG           = 7       /* Argument list too long */,
+        ENOEXEC         = 8       /* Exec format error */,
+        EBADF           = 9       /* Bad file number */,
+        ECHILD          = 10      /* No child processes */,
+        EAGAIN          = 11      /* Try again */,
+        ENOMEM          = 12      /* Out of memory */,
+        EACCES          = 13      /* Permission denied */,
+        EFAULT          = 14      /* Bad address */,
+        ENOTBLK         = 15      /* Block device required */,
+        EBUSY           = 16      /* Device or resource busy */,
+        EEXIST          = 17      /* File exists */,
+        EXDEV           = 18      /* Cross-device link */,
+        ENODEV          = 19      /* No such device */,
+        ENOTDIR         = 20      /* Not a directory */,
+        EISDIR          = 21      /* Is a directory */,
+        EINVAL          = 22      /* Invalid argument */,
+        ENFILE          = 23      /* File table overflow */,
+        EMFILE          = 24      /* Too many open files */,
+        ENOTTY          = 25      /* Not a typewriter */,
+        ETXTBSY         = 26      /* Text file busy */,
+        EFBIG           = 27      /* File too large */,
+        ENOSPC          = 28      /* No space left on device */,
+        ESPIPE          = 29      /* Illegal seek */,
+        EROFS           = 30      /* Read-only file system */,
+        EMLINK          = 31      /* Too many links */,
+        EPIPE           = 32      /* Broken pipe */,
+        EDOM            = 33      /* Math argument out of domain of func */,
+        ERANGE          = 34      /* Math result not representable */,
+        EDEADLK         = 35      /* Resource deadlock would occur */,
+        ENAMETOOLONG    = 36      /* File name too long */,
+        ENOLCK          = 37      /* No record locks available */,
+
+        /*
+         * This error code is special: arch syscall entry code will return
+         * -ENOSYS if users try to call a syscall that doesn't exist.  To keep
+         * failures of syscalls that really do exist distinguishable from
+         * failures due to attempts to use a nonexistent syscall, syscall
+         * implementations should refrain from returning -ENOSYS.
+         */
+        ENOSYS          = 38      /* Invalid system call number */,
+        ENOTEMPTY       = 39      /* Directory not empty */,
+        ELOOP           = 40      /* Too many symbolic links encountered */,
+        EWOULDBLOCK     = EAGAIN  /* Operation would block */,
+        ENOMSG          = 42      /* No message of desired type */,
+        EIDRM           = 43      /* Identifier removed */,
+        ECHRNG          = 44      /* Channel number out of range */,
+        EL2NSYNC        = 45      /* Level 2 not synchronized */,
+        EL3HLT          = 46      /* Level 3 halted */,
+        EL3RST          = 47      /* Level 3 reset */,
+        ELNRNG          = 48      /* Link number out of range */,
+        EUNATCH         = 49      /* Protocol driver not attached */,
+        ENOCSI          = 50      /* No CSI structure available */,
+        EL2HLT          = 51      /* Level 2 halted */,
+        EBADE           = 52      /* Invalid exchange */,
+        EBADR           = 53      /* Invalid request descriptor */,
+        EXFULL          = 54      /* Exchange full */,
+        ENOANO          = 55      /* No anode */,
+        EBADRQC         = 56      /* Invalid request code */,
+        EBADSLT         = 57      /* Invalid slot */,
+        EDEADLOCK       = EDEADLK,
+        EBFONT          = 59      /* Bad font file format */,
+        ENOSTR          = 60      /* Device not a stream */,
+        ENODATA         = 61      /* No data available */,
+        ETIME           = 62      /* Timer expired */,
+        ENOSR           = 63      /* Out of streams resources */,
+        ENONET          = 64      /* Machine is not on the network */,
+        ENOPKG          = 65      /* Package not installed */,
+        EREMOTE         = 66      /* Object is remote */,
+        ENOLINK         = 67      /* Link has been severed */,
+        EADV            = 68      /* Advertise error */,
+        ESRMNT          = 69      /* Srmount error */,
+        ECOMM           = 70      /* Communication error on send */,
+        EPROTO          = 71      /* Protocol error */,
+        EMULTIHOP       = 72      /* Multihop attempted */,
+        EDOTDOT         = 73      /* RFS specific error */,
+        EBADMSG         = 74      /* Not a data message */,
+        EOVERFLOW       = 75      /* Value too large for defined data type */,
+        ENOTUNIQ        = 76      /* Name not unique on network */,
+        EBADFD          = 77      /* File descriptor in bad state */,
+        EREMCHG         = 78      /* Remote address changed */,
+        ELIBACC         = 79      /* Can not access a needed shared library */,
+        ELIBBAD         = 80      /* Accessing a corrupted shared library */,
+        ELIBSCN         = 81      /* .lib section in a.out corrupted */,
+        ELIBMAX         = 82      /* Attempting to link in too many shared libraries */,
+        ELIBEXEC        = 83      /* Cannot exec a shared library directly */,
+        EILSEQ          = 84      /* Illegal byte sequence */,
+        ERESTART        = 85      /* Interrupted system call should be restarted */,
+        ESTRPIPE        = 86      /* Streams pipe error */,
+        EUSERS          = 87      /* Too many users */,
+        ENOTSOCK        = 88      /* Socket operation on non-socket */,
+        EDESTADDRREQ    = 89      /* Destination address required */,
+        EMSGSIZE        = 90      /* Message too long */,
+        EPROTOTYPE      = 91      /* Protocol wrong type for socket */,
+        ENOPROTOOPT     = 92      /* Protocol not available */,
+        EPROTONOSUPPORT = 93      /* Protocol not supported */,
+        ESOCKTNOSUPPORT = 94      /* Socket type not supported */,
+        EOPNOTSUPP      = 95      /* Operation not supported on transport endpoint */,
+        EPFNOSUPPORT    = 96      /* Protocol family not supported */,
+        EAFNOSUPPORT    = 97      /* Address family not supported by protocol */,
+        EADDRINUSE      = 98      /* Address already in use */,
+        EADDRNOTAVAIL   = 99      /* Cannot assign requested address */,
+        ENETDOWN        = 100     /* Network is down */,
+        ENETUNREACH     = 101     /* Network is unreachable */,
+        ENETRESET       = 102     /* Network dropped connection because of reset */,
+        ECONNABORTED    = 103     /* Software caused connection abort */,
+        ECONNRESET      = 104     /* Connection reset by peer */,
+        ENOBUFS         = 105     /* No buffer space available */,
+        EISCONN         = 106     /* Transport endpoint is already connected */,
+        ENOTCONN        = 107     /* Transport endpoint is not connected */,
+        ESHUTDOWN       = 108     /* Cannot send after transport endpoint shutdown */,
+        ETOOMANYREFS    = 109     /* Too many references: cannot splice */,
+        ETIMEDOUT       = 110     /* Connection timed out */,
+        ECONNREFUSED    = 111     /* Connection refused */,
+        EHOSTDOWN       = 112     /* Host is down */,
+        EHOSTUNREACH    = 113     /* No route to host */,
+        EALREADY        = 114     /* Operation already in progress */,
+        EINPROGRESS     = 115     /* Operation now in progress */,
+        ESTALE          = 116     /* Stale file handle */,
+        EUCLEAN         = 117     /* Structure needs cleaning */,
+        ENOTNAM         = 118     /* Not a XENIX named type file */,
+        ENAVAIL         = 119     /* No XENIX semaphores available */,
+        EISNAM          = 120     /* Is a named type file */,
+        EREMOTEIO       = 121     /* Remote I/O error */,
+        EDQUOT          = 122     /* Quota exceeded */,
+        ENOMEDIUM       = 123     /* No medium found */,
+        EMEDIUMTYPE     = 124     /* Wrong medium type */,
+        ECANCELED       = 125     /* Operation Canceled */,
+        ENOKEY          = 126     /* Required key not available */,
+        EKEYEXPIRED     = 127     /* Key has expired */,
+        EKEYREVOKED     = 128     /* Key has been revoked */,
+        EKEYREJECTED    = 129     /* Key was rejected by service */,
+
+        /* for robust mutexes */
+        EOWNERDEAD      = 130     /* Owner died */,
+        ENOTRECOVERABLE = 131     /* State not recoverable */,
+
+        ERFKILL         = 132     /* Operation not possible due to RF-kill */,
+
+        EHWPOISON       = 133     /* Memory page has hardware error */,
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/Utilities/WSAError.cs b/Ryujinx.HLE/Utilities/WSAError.cs
new file mode 100644
index 0000000000..55c04f2284
--- /dev/null
+++ b/Ryujinx.HLE/Utilities/WSAError.cs
@@ -0,0 +1,135 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Ryujinx.HLE.Utilities
+{
+    public enum WSAError
+    {
+        /*
+        * All Windows Sockets error constants are biased by WSABASEERR from
+        * the "normal"
+        */
+        WSABASEERR                 = 10000,
+    
+        /*
+        * Windows Sockets definitions of regular Microsoft C error constants
+        */
+        WSAEINTR                   = (WSABASEERR + 4),
+        WSAEBADF                   = (WSABASEERR + 9),
+        WSAEACCES                  = (WSABASEERR + 13),
+        WSAEFAULT                  = (WSABASEERR + 14),
+        WSAEINVAL                  = (WSABASEERR + 22),
+        WSAEMFILE                  = (WSABASEERR + 24),
+
+        /*
+         * Windows Sockets definitions of regular Berkeley error constants
+         */
+        WSAEWOULDBLOCK              = (WSABASEERR + 35),
+        WSAEINPROGRESS              = (WSABASEERR + 36),
+        WSAEALREADY                 = (WSABASEERR + 37),
+        WSAENOTSOCK                 = (WSABASEERR + 38),
+        WSAEDESTADDRREQ             = (WSABASEERR + 39),
+        WSAEMSGSIZE                 = (WSABASEERR + 40),
+        WSAEPROTOTYPE               = (WSABASEERR + 41),
+        WSAENOPROTOOPT              = (WSABASEERR + 42),
+        WSAEPROTONOSUPPORT          = (WSABASEERR + 43),
+        WSAESOCKTNOSUPPORT          = (WSABASEERR + 44),
+        WSAEOPNOTSUPP               = (WSABASEERR + 45),
+        WSAEPFNOSUPPORT             = (WSABASEERR + 46),
+        WSAEAFNOSUPPORT             = (WSABASEERR + 47),
+        WSAEADDRINUSE               = (WSABASEERR + 48),
+        WSAEADDRNOTAVAIL            = (WSABASEERR + 49),
+        WSAENETDOWN                 = (WSABASEERR + 50),
+        WSAENETUNREACH              = (WSABASEERR + 51),
+        WSAENETRESET                = (WSABASEERR + 52),
+        WSAECONNABORTED             = (WSABASEERR + 53),
+        WSAECONNRESET               = (WSABASEERR + 54),
+        WSAENOBUFS                  = (WSABASEERR + 55),
+        WSAEISCONN                  = (WSABASEERR + 56),
+        WSAENOTCONN                 = (WSABASEERR + 57),
+        WSAESHUTDOWN                = (WSABASEERR + 58),
+        WSAETOOMANYREFS             = (WSABASEERR + 59),
+        WSAETIMEDOUT                = (WSABASEERR + 60),
+        WSAECONNREFUSED             = (WSABASEERR + 61),
+        WSAELOOP                    = (WSABASEERR + 62),
+        WSAENAMETOOLONG             = (WSABASEERR + 63),
+        WSAEHOSTDOWN                = (WSABASEERR + 64),
+        WSAEHOSTUNREACH             = (WSABASEERR + 65),
+        WSAENOTEMPTY                = (WSABASEERR + 66),
+        WSAEPROCLIM                 = (WSABASEERR + 67),
+        WSAEUSERS                   = (WSABASEERR + 68),
+        WSAEDQUOT                   = (WSABASEERR + 69),
+        WSAESTALE                   = (WSABASEERR + 70),
+        WSAEREMOTE                  = (WSABASEERR + 71),
+
+        /*
+         * Extended Windows Sockets error constant definitions
+         */
+        WSASYSNOTREADY             = (WSABASEERR + 91),
+        WSAVERNOTSUPPORTED         = (WSABASEERR + 92),
+        WSANOTINITIALISED          = (WSABASEERR + 93),
+        WSAEDISCON                 = (WSABASEERR + 101),
+        WSAENOMORE                 = (WSABASEERR + 102),
+        WSAECANCELLED              = (WSABASEERR + 103),
+        WSAEINVALIDPROCTABLE       = (WSABASEERR + 104),
+        WSAEINVALIDPROVIDER        = (WSABASEERR + 105),
+        WSAEPROVIDERFAILEDINIT     = (WSABASEERR + 106),
+        WSASYSCALLFAILURE          = (WSABASEERR + 107),
+        WSASERVICE_NOT_FOUND       = (WSABASEERR + 108),
+        WSATYPE_NOT_FOUND          = (WSABASEERR + 109),
+        WSA_E_NO_MORE              = (WSABASEERR + 110),
+        WSA_E_CANCELLED            = (WSABASEERR + 111),
+        WSAEREFUSED                = (WSABASEERR + 112),
+
+        /*
+         * Error return codes from gethostbyname() and gethostbyaddr()
+         * (when using the resolver). Note that these errors are
+         * retrieved via WSAGetLastError() and must therefore follow
+         * the rules for avoiding clashes with error numbers from
+         * specific implementations or language run-time systems.
+         * For this reason the codes are based at WSABASEERR+1001.
+         * Note also that [WSA]NO_ADDRESS is defined only for
+         * compatibility purposes.
+         */
+
+        /* Authoritative Answer: Host not found */
+        WSAHOST_NOT_FOUND          = (WSABASEERR + 1001),
+
+        /* Non-Authoritative: Host not found, or SERVERFAIL */
+        WSATRY_AGAIN               = (WSABASEERR + 1002),
+
+        /* Non-recoverable errors, FORMERR, REFUSED, NOTIMP */
+        WSANO_RECOVERY             = (WSABASEERR + 1003),
+
+        /* Valid name, no data record of requested type */
+        WSANO_DATA                 = (WSABASEERR + 1004),
+
+        /*
+         * Define QOS related error return codes
+         *
+         */
+        WSA_QOS_RECEIVERS          = (WSABASEERR + 1005),
+        /* at least one Reserve has arrived */
+        WSA_QOS_SENDERS            = (WSABASEERR + 1006),
+        /* at least one Path has arrived */
+        WSA_QOS_NO_SENDERS         = (WSABASEERR + 1007),
+        /* there are no senders */
+        WSA_QOS_NO_RECEIVERS       = (WSABASEERR + 1008),
+        /* there are no receivers */
+        WSA_QOS_REQUEST_CONFIRMED  = (WSABASEERR + 1009),
+        /* Reserve has been confirmed */
+        WSA_QOS_ADMISSION_FAILURE  = (WSABASEERR + 1010),
+        /* error due to lack of resources */
+        WSA_QOS_POLICY_FAILURE     = (WSABASEERR + 1011),
+        /* rejected for administrative reasons - bad credentials */
+        WSA_QOS_BAD_STYLE          = (WSABASEERR + 1012),
+        /* unknown or conflicting style */
+        WSA_QOS_BAD_OBJECT         = (WSABASEERR + 1013),
+        /* problem with some part of the filterspec or providerspecific
+         * buffer in general */
+        WSA_QOS_TRAFFIC_CTRL_ERROR = (WSABASEERR + 1014),
+        /* problem with some part of the flowspec */
+        WSA_QOS_GENERIC_ERROR      = (WSABASEERR + 1015),
+    }
+}