// GetHostStringErrorRequest(u32) -> buffer<unknown, 6, 0> public ResultCode GetHostStringErrorRequest(ServiceCtx context) { ResultCode resultCode = ResultCode.NotAllocated; NetDbError errorCode = (NetDbError)context.RequestData.ReadInt32(); string errorString = errorCode switch { NetDbError.Success => "Resolver Error 0 (no error)", NetDbError.HostNotFound => "Unknown host", NetDbError.TryAgain => "Host name lookup failure", NetDbError.NoRecovery => "Unknown server error", NetDbError.NoData => "No address associated with name", _ => (errorCode <= NetDbError.Internal) ? "Resolver internal error" : "Unknown resolver error" }; long bufferPosition = context.Request.ReceiveBuff[0].Position; long bufferSize = context.Request.ReceiveBuff[0].Size; if (errorString.Length + 1 <= bufferSize) { context.Memory.Write((ulong)bufferPosition, Encoding.ASCII.GetBytes(errorString + '\0')); resultCode = ResultCode.Success; } return(resultCode); }
private string GetHostStringErrorFromErrorCode(NetDbError errorCode) { if (errorCode <= NetDbError.Internal) { return("Resolver internal error"); } switch (errorCode) { case NetDbError.Success: return("Resolver Error 0 (no error)"); case NetDbError.HostNotFound: return("Unknown host"); case NetDbError.TryAgain: return("Host name lookup failure"); case NetDbError.NoRecovery: return("Unknown server error"); case NetDbError.NoData: return("No address associated with name"); default: return("Unknown resolver error"); } }
private ResultCode GetHostByAddrRequestImpl(ServiceCtx context, long inputBufferPosition, long inputBufferSize, long outputBufferPosition, long outputBufferSize, long optionsBufferPosition, long optionsBufferSize) { byte[] rawIp = new byte[inputBufferSize]; context.Memory.Read((ulong)inputBufferPosition, rawIp); // TODO: Use params. uint socketLength = context.RequestData.ReadUInt32(); uint type = context.RequestData.ReadUInt32(); int timeOut = context.RequestData.ReadInt32(); ulong pidPlaceholder = context.RequestData.ReadUInt64(); if (optionsBufferSize > 0) { // TODO: Parse and use options. } IPHostEntry hostEntry = null; NetDbError netDbErrorCode = NetDbError.Success; GaiError errno = GaiError.AddressFamily; long serializedSize = 0; if (rawIp.Length == 4) { try { IPAddress address = new IPAddress(rawIp); hostEntry = Dns.GetHostEntry(address); } catch (SocketException exception) { netDbErrorCode = ConvertSocketErrorCodeToNetDbError(exception.ErrorCode); errno = ConvertSocketErrorCodeToGaiError(exception.ErrorCode, errno); } } else { netDbErrorCode = NetDbError.NoAddress; } if (hostEntry != null) { errno = GaiError.Success; serializedSize = SerializeHostEntries(context, outputBufferPosition, outputBufferSize, hostEntry, GetIpv4Addresses(hostEntry)); } context.ResponseData.Write((int)netDbErrorCode); context.ResponseData.Write((int)errno); context.ResponseData.Write(serializedSize); return(ResultCode.Success); }
// GetHostStringError(u32) -> buffer<unknown, 6, 0> public ResultCode GetHostStringError(ServiceCtx context) { ResultCode resultCode = ResultCode.NotAllocated; NetDbError errorCode = (NetDbError)context.RequestData.ReadInt32(); string errorString = GetHostStringErrorFromErrorCode(errorCode); if (errorString.Length + 1 <= context.Request.ReceiveBuff[0].Size) { resultCode = 0; context.Memory.WriteBytes(context.Request.ReceiveBuff[0].Position, Encoding.ASCII.GetBytes(errorString + '\0')); } return(resultCode); }
// GetHostStringError(u32) -> buffer<unknown, 6, 0> public long GetHostStringError(ServiceCtx context) { long resultCode = MakeError(ErrorModule.Os, 1023); NetDbError errorCode = (NetDbError)context.RequestData.ReadInt32(); string errorString = GetHostStringErrorFromErrorCode(errorCode); if (errorString.Length + 1 <= context.Request.ReceiveBuff[0].Size) { resultCode = 0; context.Memory.WriteBytes(context.Request.ReceiveBuff[0].Position, Encoding.ASCII.GetBytes(errorString + '\0')); } return(resultCode); }
private static void WriteResponse( ServiceCtx context, bool withOptions, ulong serializedSize, GaiError errno, NetDbError netDbErrorCode) { if (withOptions) { context.ResponseData.Write((int)serializedSize); context.ResponseData.Write((int)errno); context.ResponseData.Write((int)netDbErrorCode); context.ResponseData.Write(0); } else { context.ResponseData.Write((int)netDbErrorCode); context.ResponseData.Write((int)errno); context.ResponseData.Write((int)serializedSize); } }
[CommandHipc(14)] // 5.0.0+ // ResolverSetOptionRequest(buffer<unknown, 5, 0>, u64 unknown, u64 pid_placeholder, pid) -> (i32 ret, u32 bsd_errno) public ResultCode ResolverSetOptionRequest(ServiceCtx context) { ulong bufferPosition = context.Request.SendBuff[0].Position; ulong bufferSize = context.Request.SendBuff[0].Size; ulong unknown = context.RequestData.ReadUInt64(); byte[] buffer = new byte[bufferSize]; context.Memory.Read(bufferPosition, buffer); // TODO: Parse and use options. Logger.Stub?.PrintStub(LogClass.ServiceSfdnsres, new { unknown }); NetDbError netDbErrorCode = NetDbError.Success; GaiError errno = GaiError.Success; context.ResponseData.Write((int)errno); context.ResponseData.Write((int)netDbErrorCode); return(ResultCode.Success); }
private ResultCode GetAddrInfoRequestImpl(ServiceCtx context, long responseBufferPosition, long responseBufferSize, long optionsBufferPosition, long optionsBufferSize) { bool enableNsdResolve = (context.RequestData.ReadInt32() & 1) != 0; uint cancelHandle = context.RequestData.ReadUInt32(); string host = MemoryHelper.ReadAsciiString(context.Memory, context.Request.SendBuff[0].Position, context.Request.SendBuff[0].Size); string service = MemoryHelper.ReadAsciiString(context.Memory, context.Request.SendBuff[1].Position, context.Request.SendBuff[1].Size); // NOTE: We ignore hints for now. DeserializeAddrInfos(context.Memory, (ulong)context.Request.SendBuff[2].Position, (ulong)context.Request.SendBuff[2].Size); if (optionsBufferSize > 0) { // TODO: Find unknown, Parse and use options. uint unknown = context.RequestData.ReadUInt32(); } ulong pidPlaceHolder = context.RequestData.ReadUInt64(); Logger.Stub?.PrintStub(LogClass.ServiceSfdnsres, new { enableNsdResolve, cancelHandle, pidPlaceHolder, host, service }); IPHostEntry hostEntry = null; NetDbError netDbErrorCode = NetDbError.Success; GaiError errno = GaiError.AddressFamily; ulong serializedSize = 0; if (host.Length <= byte.MaxValue) { string targetHost = host; if (DnsBlacklist.IsHostBlocked(host)) { Logger.Info?.Print(LogClass.ServiceSfdnsres, $"DNS Blocked: {host}"); netDbErrorCode = NetDbError.HostNotFound; errno = GaiError.NoData; } else { Logger.Info?.Print(LogClass.ServiceSfdnsres, $"Trying to resolve: {host}"); try { hostEntry = Dns.GetHostEntry(targetHost); } catch (SocketException exception) { netDbErrorCode = ConvertSocketErrorCodeToNetDbError(exception.ErrorCode); errno = ConvertSocketErrorCodeToGaiError(exception.ErrorCode, errno); } } } else { netDbErrorCode = NetDbError.NoAddress; } if (hostEntry != null) { int.TryParse(service, out int port); errno = GaiError.Success; serializedSize = SerializeAddrInfos(context, responseBufferPosition, responseBufferSize, hostEntry, port); } context.ResponseData.Write((int)netDbErrorCode); context.ResponseData.Write((int)errno); context.ResponseData.Write(serializedSize); return(ResultCode.Success); }
private ResultCode GetHostByNameRequestImpl(ServiceCtx context, long inputBufferPosition, long inputBufferSize, long outputBufferPosition, long outputBufferSize, long optionsBufferPosition, long optionsBufferSize) { byte[] rawName = new byte[inputBufferSize]; context.Memory.Read((ulong)inputBufferPosition, rawName); string name = Encoding.ASCII.GetString(rawName).TrimEnd('\0'); // TODO: Use params. bool enableNsdResolve = (context.RequestData.ReadInt32() & 1) != 0; int timeOut = context.RequestData.ReadInt32(); ulong pidPlaceholder = context.RequestData.ReadUInt64(); if (optionsBufferSize > 0) { // TODO: Parse and use options. } IPHostEntry hostEntry = null; NetDbError netDbErrorCode = NetDbError.Success; GaiError errno = GaiError.Overflow; long serializedSize = 0; if (name.Length <= byte.MaxValue) { string targetHost = name; if (DnsBlacklist.IsHostBlocked(name)) { Logger.Info?.Print(LogClass.ServiceSfdnsres, $"DNS Blocked: {name}"); netDbErrorCode = NetDbError.HostNotFound; errno = GaiError.NoData; } else { Logger.Info?.Print(LogClass.ServiceSfdnsres, $"Trying to resolve: {name}"); try { hostEntry = Dns.GetHostEntry(targetHost); } catch (SocketException exception) { netDbErrorCode = ConvertSocketErrorCodeToNetDbError(exception.ErrorCode); errno = ConvertSocketErrorCodeToGaiError(exception.ErrorCode, errno); } } } else { netDbErrorCode = NetDbError.HostNotFound; } if (hostEntry != null) { IEnumerable <IPAddress> addresses = GetIpv4Addresses(hostEntry); if (!addresses.Any()) { errno = GaiError.NoData; netDbErrorCode = NetDbError.NoAddress; } else { errno = GaiError.Success; serializedSize = SerializeHostEntries(context, outputBufferPosition, outputBufferSize, hostEntry, addresses); } } context.ResponseData.Write((int)netDbErrorCode); context.ResponseData.Write((int)errno); context.ResponseData.Write(serializedSize); return(ResultCode.Success); }
// GetHostByAddr(u32, u32, u32, u64, pid, buffer<unknown, 5, 0>) -> (u32, u32, u32, buffer<unknown, 6, 0>) public ResultCode GetHostByAddress(ServiceCtx context) { byte[] rawIp = context.Memory.ReadBytes(context.Request.SendBuff[0].Position, context.Request.SendBuff[0].Size); // TODO: use params uint socketLength = context.RequestData.ReadUInt32(); uint type = context.RequestData.ReadUInt32(); int timeOut = context.RequestData.ReadInt32(); ulong pidPlaceholder = context.RequestData.ReadUInt64(); IPHostEntry hostEntry = null; NetDbError netDbErrorCode = NetDbError.Success; GaiError errno = GaiError.AddressFamily; long serializedSize = 0; if (rawIp.Length == 4) { try { IPAddress address = new IPAddress(rawIp); hostEntry = Dns.GetHostEntry(address); } catch (SocketException exception) { netDbErrorCode = NetDbError.Internal; if (exception.ErrorCode == 11001) { netDbErrorCode = NetDbError.HostNotFound; errno = GaiError.NoData; } else if (exception.ErrorCode == 11002) { netDbErrorCode = NetDbError.TryAgain; } else if (exception.ErrorCode == 11003) { netDbErrorCode = NetDbError.NoRecovery; } else if (exception.ErrorCode == 11004) { netDbErrorCode = NetDbError.NoData; } else if (exception.ErrorCode == 10060) { errno = GaiError.Again; } } } else { netDbErrorCode = NetDbError.NoAddress; } if (hostEntry != null) { errno = GaiError.Success; serializedSize = SerializeHostEnt(context, hostEntry, GetIpv4Addresses(hostEntry)); } context.ResponseData.Write((int)netDbErrorCode); context.ResponseData.Write((int)errno); context.ResponseData.Write(serializedSize); return(ResultCode.Success); }
// GetHostByName(u8, u32, u64, pid, buffer<unknown, 5, 0>) -> (u32, u32, u32, buffer<unknown, 6, 0>) public ResultCode GetHostByName(ServiceCtx context) { byte[] rawName = context.Memory.ReadBytes(context.Request.SendBuff[0].Position, context.Request.SendBuff[0].Size); string name = Encoding.ASCII.GetString(rawName).TrimEnd('\0'); // TODO: use params bool enableNsdResolve = context.RequestData.ReadInt32() == 1; int timeOut = context.RequestData.ReadInt32(); ulong pidPlaceholder = context.RequestData.ReadUInt64(); IPHostEntry hostEntry = null; NetDbError netDbErrorCode = NetDbError.Success; GaiError errno = GaiError.Overflow; long serializedSize = 0; if (name.Length <= 255) { try { hostEntry = Dns.GetHostEntry(name); } catch (SocketException exception) { netDbErrorCode = NetDbError.Internal; if (exception.ErrorCode == 11001) { netDbErrorCode = NetDbError.HostNotFound; errno = GaiError.NoData; } else if (exception.ErrorCode == 11002) { netDbErrorCode = NetDbError.TryAgain; } else if (exception.ErrorCode == 11003) { netDbErrorCode = NetDbError.NoRecovery; } else if (exception.ErrorCode == 11004) { netDbErrorCode = NetDbError.NoData; } else if (exception.ErrorCode == 10060) { errno = GaiError.Again; } } } else { netDbErrorCode = NetDbError.HostNotFound; } if (hostEntry != null) { errno = GaiError.Success; List <IPAddress> addresses = GetIpv4Addresses(hostEntry); if (addresses.Count == 0) { errno = GaiError.NoData; netDbErrorCode = NetDbError.NoAddress; } else { serializedSize = SerializeHostEnt(context, hostEntry, addresses); } } context.ResponseData.Write((int)netDbErrorCode); context.ResponseData.Write((int)errno); context.ResponseData.Write(serializedSize); return(ResultCode.Success); }
private static ResultCode GetAddrInfoRequestImpl( ServiceCtx context, ulong responseBufferPosition, ulong responseBufferSize, bool withOptions, ulong optionsBufferPosition, ulong optionsBufferSize) { bool enableNsdResolve = (context.RequestData.ReadInt32() & 1) != 0; uint cancelHandle = context.RequestData.ReadUInt32(); string host = MemoryHelper.ReadAsciiString(context.Memory, context.Request.SendBuff[0].Position, (long)context.Request.SendBuff[0].Size); string service = MemoryHelper.ReadAsciiString(context.Memory, context.Request.SendBuff[1].Position, (long)context.Request.SendBuff[1].Size); if (!context.Device.Configuration.EnableInternetAccess) { Logger.Info?.Print(LogClass.ServiceSfdnsres, $"Guest network access disabled, DNS Blocked: {host}"); WriteResponse(context, withOptions, 0, GaiError.NoData, NetDbError.HostNotFound); return(ResultCode.Success); } // NOTE: We ignore hints for now. DeserializeAddrInfos(context.Memory, (ulong)context.Request.SendBuff[2].Position, (ulong)context.Request.SendBuff[2].Size); if (withOptions) { // TODO: Find unknown, Parse and use options. uint unknown = context.RequestData.ReadUInt32(); } ulong pidPlaceHolder = context.RequestData.ReadUInt64(); IPHostEntry hostEntry = null; NetDbError netDbErrorCode = NetDbError.Success; GaiError errno = GaiError.AddressFamily; ulong serializedSize = 0; if (host.Length <= byte.MaxValue) { if (enableNsdResolve) { if (FqdnResolver.Resolve(host, out string newAddress) == Nsd.ResultCode.Success) { host = newAddress; } } string targetHost = host; if (DnsBlacklist.IsHostBlocked(host)) { Logger.Info?.Print(LogClass.ServiceSfdnsres, $"DNS Blocked: {host}"); netDbErrorCode = NetDbError.HostNotFound; errno = GaiError.NoData; } else { Logger.Info?.Print(LogClass.ServiceSfdnsres, $"Trying to resolve: {host}"); try { hostEntry = Dns.GetHostEntry(targetHost); } catch (SocketException exception) { netDbErrorCode = ConvertSocketErrorCodeToNetDbError(exception.ErrorCode); errno = ConvertSocketErrorCodeToGaiError(exception.ErrorCode, errno); } } } else { netDbErrorCode = NetDbError.NoAddress; } if (hostEntry != null) { int.TryParse(service, out int port); errno = GaiError.Success; serializedSize = SerializeAddrInfos(context, responseBufferPosition, responseBufferSize, hostEntry, port); } WriteResponse(context, withOptions, serializedSize, errno, netDbErrorCode); return(ResultCode.Success); }
private static ResultCode GetHostByAddrRequestImpl( ServiceCtx context, ulong inputBufferPosition, ulong inputBufferSize, ulong outputBufferPosition, ulong outputBufferSize, bool withOptions, ulong optionsBufferPosition, ulong optionsBufferSize) { if (!context.Device.Configuration.EnableInternetAccess) { Logger.Info?.Print(LogClass.ServiceSfdnsres, $"Guest network access disabled, DNS Blocked."); WriteResponse(context, withOptions, 0, GaiError.NoData, NetDbError.HostNotFound); return(ResultCode.Success); } byte[] rawIp = new byte[inputBufferSize]; context.Memory.Read(inputBufferPosition, rawIp); // TODO: Use params. uint socketLength = context.RequestData.ReadUInt32(); uint type = context.RequestData.ReadUInt32(); int timeOut = context.RequestData.ReadInt32(); ulong pidPlaceholder = context.RequestData.ReadUInt64(); if (withOptions) { // TODO: Parse and use options. } IPHostEntry hostEntry = null; NetDbError netDbErrorCode = NetDbError.Success; GaiError errno = GaiError.AddressFamily; ulong serializedSize = 0; if (rawIp.Length == 4) { try { IPAddress address = new IPAddress(rawIp); hostEntry = Dns.GetHostEntry(address); } catch (SocketException exception) { netDbErrorCode = ConvertSocketErrorCodeToNetDbError(exception.ErrorCode); errno = ConvertSocketErrorCodeToGaiError(exception.ErrorCode, errno); } } else { netDbErrorCode = NetDbError.NoAddress; } if (hostEntry != null) { errno = GaiError.Success; serializedSize = SerializeHostEntries(context, outputBufferPosition, outputBufferSize, hostEntry, GetIpv4Addresses(hostEntry)); } WriteResponse(context, withOptions, serializedSize, errno, netDbErrorCode); return(ResultCode.Success); }
private static ResultCode GetHostByNameRequestImpl( ServiceCtx context, ulong inputBufferPosition, ulong inputBufferSize, ulong outputBufferPosition, ulong outputBufferSize, bool withOptions, ulong optionsBufferPosition, ulong optionsBufferSize) { string host = MemoryHelper.ReadAsciiString(context.Memory, inputBufferPosition, (int)inputBufferSize); if (!context.Device.Configuration.EnableInternetAccess) { Logger.Info?.Print(LogClass.ServiceSfdnsres, $"Guest network access disabled, DNS Blocked: {host}"); WriteResponse(context, withOptions, 0, GaiError.NoData, NetDbError.HostNotFound); return(ResultCode.Success); } // TODO: Use params. bool enableNsdResolve = (context.RequestData.ReadInt32() & 1) != 0; int timeOut = context.RequestData.ReadInt32(); ulong pidPlaceholder = context.RequestData.ReadUInt64(); if (withOptions) { // TODO: Parse and use options. } IPHostEntry hostEntry = null; NetDbError netDbErrorCode = NetDbError.Success; GaiError errno = GaiError.Overflow; ulong serializedSize = 0; if (host.Length <= byte.MaxValue) { if (enableNsdResolve) { if (FqdnResolver.Resolve(host, out string newAddress) == Nsd.ResultCode.Success) { host = newAddress; } } string targetHost = host; if (DnsBlacklist.IsHostBlocked(host)) { Logger.Info?.Print(LogClass.ServiceSfdnsres, $"DNS Blocked: {host}"); netDbErrorCode = NetDbError.HostNotFound; errno = GaiError.NoData; } else { Logger.Info?.Print(LogClass.ServiceSfdnsres, $"Trying to resolve: {host}"); try { hostEntry = Dns.GetHostEntry(targetHost); } catch (SocketException exception) { netDbErrorCode = ConvertSocketErrorCodeToNetDbError(exception.ErrorCode); errno = ConvertSocketErrorCodeToGaiError(exception.ErrorCode, errno); } } } else { netDbErrorCode = NetDbError.HostNotFound; } if (hostEntry != null) { IEnumerable <IPAddress> addresses = GetIpv4Addresses(hostEntry); if (!addresses.Any()) { errno = GaiError.NoData; netDbErrorCode = NetDbError.NoAddress; } else { errno = GaiError.Success; serializedSize = SerializeHostEntries(context, outputBufferPosition, outputBufferSize, hostEntry, addresses); } } WriteResponse(context, withOptions, serializedSize, errno, netDbErrorCode); return(ResultCode.Success); }