private ResultCode SocketInternal(ServiceCtx context, bool exempt) { BsdAddressFamily domain = (BsdAddressFamily)context.RequestData.ReadInt32(); BsdSocketType type = (BsdSocketType)context.RequestData.ReadInt32(); ProtocolType protocol = (ProtocolType)context.RequestData.ReadInt32(); BsdSocketCreationFlags creationFlags = (BsdSocketCreationFlags)((int)type >> (int)BsdSocketCreationFlags.FlagsShift); type &= BsdSocketType.TypeMask; if (domain == BsdAddressFamily.Unknown) { return(WriteBsdResult(context, -1, LinuxError.EPROTONOSUPPORT)); } else if ((type == BsdSocketType.Seqpacket || type == BsdSocketType.Raw) && !_isPrivileged) { if (domain != BsdAddressFamily.InterNetwork || type != BsdSocketType.Raw || protocol != ProtocolType.Icmp) { return(WriteBsdResult(context, -1, LinuxError.ENOENT)); } } AddressFamily netDomain = ConvertBsdAddressFamily(domain); if (protocol == ProtocolType.IP) { if (type == BsdSocketType.Stream) { protocol = ProtocolType.Tcp; } else if (type == BsdSocketType.Dgram) { protocol = ProtocolType.Udp; } } ISocket newBsdSocket = new ManagedSocket(netDomain, (SocketType)type, protocol); newBsdSocket.Blocking = !creationFlags.HasFlag(BsdSocketCreationFlags.NonBlocking); LinuxError errno = LinuxError.SUCCESS; int newSockFd = _context.RegisterFileDescriptor(newBsdSocket); if (newSockFd == -1) { errno = LinuxError.EBADF; } if (exempt) { newBsdSocket.Disconnect(); } return(WriteBsdResult(context, newSockFd, errno)); }
private static AddressFamily ConvertBsdAddressFamily(BsdAddressFamily family) { switch (family) { case BsdAddressFamily.Unspecified: return(AddressFamily.Unspecified); case BsdAddressFamily.InterNetwork: return(AddressFamily.InterNetwork); case BsdAddressFamily.InterNetworkV6: return(AddressFamily.InterNetworkV6); case BsdAddressFamily.Unknown: return(AddressFamily.Unknown); default: throw new NotImplementedException(family.ToString()); } }