Sockets services
bsd:u, bsd:s, bsd:a
This is "nn::socket::sf::IClient".
[15.0.0+] This is "nn::socket::sf::IClient_MC".
[18.0.0+] This is "nn::socket::sf::IClient".
All the services commands but the first two return -1 on failure and set errno when that happens. Although Nintendo has the FreeBSD kernel's to socket stack, the errno macro definitions being in use actually come from Linux (and not from FreeBSD as one would expect!).
[18.0.0+] bsd:a was added.
These services have max_sessions 0x40. There's 22 IPC handler threads for bsd:u, and 11 for bsd:s.
[16.0.0+] bsd:u has max_sessions 0x24 and bsd:s has max_sessions 0x7E.
[18.0.0+] bsd:u has max_sessions 0xF, bsd:s has max_sessions 0x7E and bsd:a has max_sessions 0x17.
Cmd | Name |
---|---|
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 |
28 | #GetResourceStatistics |
29 | [3.0.0+] #RecvMMsg |
30 | [3.0.0+] #SendMMsg |
31 | [7.0.0+] EventFd |
32 | [7.0.0+] #RegisterResourceStatisticsName |
33 | [10.0.0+] #RegisterClientShared |
34 | [15.0.0+] GetSocketStatistics |
35 | [17.0.0+] NifIoctl |
200 | [15.0.0+] SetThreadCoreMask |
201 | [15.0.0+] GetThreadCoreMask |
RegisterClient
Takes a #LibraryConfigData, the PID, the size of the transfer memory and a copy-handle of the latter.
The transfer memory must be larger than a the computed size below. Should the transfer memory be smaller than that, the BSD sockets service would only send ZeroWindow packets (for TCP), resulting in a transfer rate not exceeding 1 byte/s.
static size_t _bsdGetTransferMemSizeForBufferConfig(const BsdBufferConfig *config) { u32 tcp_tx_buf_max_size = config->tcp_tx_buf_max_size != 0 ? config->tcp_tx_buf_max_size : config->tcp_tx_buf_size; u32 tcp_rx_buf_max_size = config->tcp_rx_buf_max_size != 0 ? config->tcp_rx_buf_max_size : config->tcp_rx_buf_size; u32 sum = tcp_tx_buf_max_size + tcp_rx_buf_max_size + config->udp_tx_buf_size + config->udp_rx_buf_size; sum = ((sum + 0xFFF) >> 12) << 12; // page round-up return (size_t)(config->sb_efficiency * sum); }
Socket
FreeBSD's socket
command.
bsd:u
disallows the usage of the SOCK_SEQPACKET
and SOCK_RAW
types, with the exception of (AF_INET, SOCK_RAW, IPPROTO_ICMP)
(IPv4 ping
), bsd:s
needs to be used for those.
The only registered domains are AF_INET
and AF_ROUTE
.
SocketExempt: same as socket but the socket is immediately shutdown (disconnected) on creation.
Open
FreeBSD's open
command, limited to opening /dev/bpf
. This can be used, for example, to enable promiscuous mode, see FreeBSD's /dev/bpf
for more details.
Sysctl
FreeBSD's sysctl
command. Privileged operations are reserved for bsd:s
.
CTL_NET
, CTL_VM
, CTL_KERN
and CTL_DEBUG
commands are implemented (?).
Ioctl
FreeBSD's ioctl
function. The following ioctls are whitelisted, refer to FreeBSD's headers for more details: SIOCATMARK, BIOCGBLEN, BIOCSETF BIOCIMMEDIATE, BIOCSETIF, BIOCVERSION, FIONSPACE, FIONWRITE, FIONREAD, SIOCGETSGCNT, SIOCGIFMETRIC, SIOCSIFMETRIC, SIOCDIFADDR, SIOCGIFINDEX, SIOCGIFADDR, SIOCGIFCONF, SIOCGIFNETMASK, SIOCAIFADDR, SIOCGIFMTU, SIOCSIFMTU, SIOCGIFMEDIA, SIOCSIFLLADDR and SIOCGIFXMEDIA.
Nintendo use the following definition (hence changing all ioctls using this structure):
struct bpf_program { u_int bf_len; struct bpf_insn bf_insns[BPF_MAXINSNS]; // [512]. This is a pointer in the official structure };
Fcntl
FreeBSD's fcntl
, limited to F_GETFL
and F_SETFL
with O_NONBLOCK
.
DuplicateSocket
Takes a socket file descriptor and an unused u64. Duplicates the socket (FreeBSD's dup
). Reserved to bsd:s
.
GetResourceStatistics
Takes a total of 8-bytes of input, a PID, a type-0x22 output buffer, and returns a total of 8-bytes of output.
[4.0.0+] Now takes an additional 8-bytes of input.
[7.0.0+] Now takes an additional type-0x21 input buffer.
RecvMMsg
Takes a total of 0x20-bytes of input, a type-0x22 output buffer, and returns a total of 8-bytes of output.
[7.0.0+] The buffer was replaced with a type-0x6 output buffer.
SendMMsg
Takes a total of 0xC-bytes of input, two type-0x21 input buffers, and returns a total of 8-bytes of output.
[7.0.0+] The buffers were replaced with a type-0x6 output buffer.
RegisterResourceStatisticsName
With [10.0.0+] this now takes an additional 8-bytes of input.
Same input/output as #RegisterClient except this doesn't take an input handle.
The work-buffer (size is still specified with this cmd) is backed by memory in the sysmodule, instead of TransferMemory. The size (after alignment) must be >=0x1000 and <=0x13F000.
sdknso will only use this cmd when two flags in the input config are set: the first one being set indicates that the bsd:s service is used, while the second flag enables using this cmd. An error is thrown if the work-buffer size is <0x1000. Otherwise when these flags aren't set, #RegisterClient is used as usual.
bsdcfg, ifcfg
This is "nn::bsdsocket::cfg::ServerInterface".
[17.0.0+] ifcfg was added.
This has max_sessions 4.
[18.0.0+] bsdcfg has max_sessions 1 and ifcfg has max_sessions 4.
Cmd | Name |
---|---|
0 | #SetIfUp |
1 | #SetIfUpWithEvent |
2 | CancelIf |
3 | SetIfDown |
4 | GetIfState |
5 | DhcpRenew |
6 | AddStaticArpEntry |
7 | RemoveArpEntry |
8 | LookupArpEntry |
9 | LookupArpEntry2 |
10 | ClearArpEntries |
11 | ClearArpEntries2 |
12 | PrintArpEntries |
13 | [16.0.0+] |
14 | [16.0.0+] |
15 | [16.0.0+] |
16 | [17.0.0+] |
17 | [17.0.0+] |
18 | [17.0.0+] |
19 | [17.0.0+] |
20 | [17.0.0+] |
21 | [17.0.0+] |
22 | [17.0.0+] |
23 | [17.0.0+] |
50 | [17.0.0+] |
51 | [17.0.0+] |
52 | [17.0.0+] |
53 | [17.0.0+] |
54 | [17.0.0+] |
55 | [17.0.0+] |
56 | [17.0.0+] |
57 | [17.0.0+] |
58 | [17.0.0+] |
100 | [17.0.0+] |
SetIfUp
Takes a total of 0x28-bytes of input and a type-0x5 input buffer, no output.
[3.0.0+] Takes an additional 4-bytes of input.
SetIfUpWithEvent
Takes a total of 0x28-bytes of input and a type-0x5 input buffer, returns an output handle.
[3.0.0+] Takes an additional 4-bytes of input.
Cmd13
Takes a type-0x5 input buffer, no output.
Stubbed, just returns 0.
Cmd14
Takes a type-0x5 input buffer, no output.
Stubbed, just returns 0.
Cmd15
Takes a type-0x5 input buffer, no output.
Stubbed, just returns 0.
ethc:c
This is "nn::eth::sf::IEthInterface".
This service no longer exists in [15.0.0+].
Cmd | Name |
---|---|
0 | Initialize |
1 | Cancel |
2 | GetResult |
3 | GetMediaList |
4 | SetMediaType |
5 | GetMediaType |
6 | [11.0.0+] GetMacAddress |
ethc:i
This is "nn::eth::sf::IEthInterfaceGroup".
This service no longer exists in [15.0.0+].
Cmd | Name |
---|---|
0 | GetReadableHandle |
1 | Cancel |
2 | GetResult |
3 | GetInterfaceList |
4 | GetInterfaceCount |
sfdnsres
This is "nn::socket::resolver::IResolver".
This service uses bionic/libc/dns
to perform its tasks.
This has max_sessions 8 and 8 IPC handler threads.
Cmd | Name |
---|---|
0 | SetDnsAddressesPrivateRequest |
1 | GetDnsAddressPrivateRequest |
2 | GetHostByNameRequest |
3 | GetHostByAddrRequest |
4 | GetHostStringErrorRequest |
5 | GetGaiStringErrorRequest |
6 | #GetAddrInfoRequest |
7 | GetNameInfoRequest |
8 | GetCancelHandleRequest |
9 | CancelRequest |
10 | [5.0.0+] GetHostByNameRequestWithOptions |
11 | [5.0.0+] GetHostByAddrRequestWithOptions |
12 | [5.0.0+] GetAddrInfoRequestWithOptions |
13 | [5.0.0+] GetNameInfoRequestWithOptions |
14 | [5.0.0+] ResolverSetOptionRequest |
15 | [5.0.0+] ResolverGetOptionRequest |
GetAddrInfoRequest
Takes three type 5 buffers (host, port, and hints), and a type 6 buffer (the output addrinfos). Also takes a u8 (padded to 4 bytes so the next raw parameter can align), a u32, and a u64. The u8 is a boolean for whether to enable "nsd resolve" (1) or not (0). Not sure what the u32 is. It seems to either come from a parameter to GetAddrInfo or be zero. The u64 is most likely a placeholder for the server to copy the PID into and should be zero. Both hints and the output buffer contain serialized addrinfo chains. The hints buffer is sized 0x400 bytes long by default, and the output buffer 0x1000 bytes.
On newer versions this calls the same vfunc as GetAddrInfoRequestWithOptions, except with fixed Options.
Addrinfo Serialization Format
Each struct addrinfo in the linked list is serialized according to this format and then written to the buffer. All numbers are in network byte order.
Size (bytes) | Name | Notes |
---|---|---|
4 | Magic | Needs to be 0xBEEFCAFE. Seriously. |
4 | ai_flags | |
4 | ai_family | |
4 | ai_socktype | |
4 | ai_protocol | |
4 | ai_addrlen | |
ai_addrlen ? ai_addrlen : 4 | ai_addr | |
null-terminated string | ai_canonname |
If ai_addrlen is zero, ai_addr will occupy 4 bytes.
Size (bytes) | Name | Notes |
---|---|---|
4 | ai_addr |
If ai_family is recognized as AF_INET6 (28) or AF_INET (2), ai_addr is read as struct sockaddr_in or struct sockaddr_in6. Otherwise, it's just read as u8[ai_addrlen].
The list should be terminated with a sentinel four-byte zero value.
dns:priv
This is "nn::socket::resolver::IPrivateResolver".
This was added with [18.0.0+].
This has max_sessions 1.
Cmd | Name |
---|---|
0 | |
1 | |
2 |
nsd:u, nsd:a
This is "nn::nsd::detail::IManager".
nsd:u has max_sessions 20, nsd:a has IPC max_sessions 5. No retail system titles have access to nsd:a.
Cmd | Name |
---|---|
5 | [11.0.0+] #GetSettingUrl |
10 | #GetSettingName |
11 | #GetEnvironmentIdentifier |
12 | #GetDeviceId |
13 | #DeleteSettings |
14 | #ImportSettings |
15 | [4.0.0+] #SetChangeEnvironmentIdentifierDisabled |
20 | #Resolve |
21 | #ResolveEx |
30 | #GetNasServiceSetting |
31 | #GetNasServiceSettingEx |
40 | #GetNasRequestFqdn |
41 | #GetNasRequestFqdnEx |
42 | #GetNasApiFqdn |
43 | #GetNasApiFqdnEx |
50 | #GetCurrentSetting |
51 | [9.0.0+] #WriteTestParameter |
52 | [9.0.0+] #ReadTestParameter |
60 | #ReadSaveDataFromFsForTest |
61 | #WriteSaveDataToFsForTest |
62 | #DeleteSaveDataOfFsForTest |
63 | [4.0.0+] #IsChangeEnvironmentIdentifierDisabled |
64 | [10.0.0+] #SetWithoutDomainExchangeFqdns |
100 | [10.0.0+] #GetApplicationServerEnvironmentType |
101 | [10.0.0+] #SetApplicationServerEnvironmentType |
102 | [10.0.0+] #DeleteApplicationServerEnvironmentType |
GetSettingUrl
Takes a type-0x16 output buffer containing an #Url.
Gets the 0x100-byte sys-setting for nsd!setting_url
with the data being located on stack, memcpys the 0x100-bytes to the output buffer, then returns 0.
With newer sysvers, after loading the sys-setting it checks if the first 8-bytes match "https://", when it doesn't match then the tmp data on stack is overwritten with an #Url for "https://api.sect.srv.nintendo.net/v1/setting" (which is also the default value of this sys-setting). Prior to loading the sys-setting it also checks the size of the sys-setting (setsys GetSettingsItemValueSize), jumping to this memcpy-block when the size is 0.
GetSettingName
Takes a type-0x16 output buffer containing a #SettingName.
Calls a func with output located on stack. If successful the 0x100-bytes from there is memcpy'd to the output buffer, then returns 0.
That func eventually memcpys data from state, if available.
GetEnvironmentIdentifier
Takes a type-0x16 buffer containing an #EnvironmentIdentifier.
The output string is used by NIM for the "eid:%s" in the User-Agent strings.
This is the "lp1" string also used in domains.
GetDeviceId
No input, returns a #DeviceId.
Stubbed, just returns 0.
DeleteSettings
Takes an input #DeleteMode, no output.
This is only usable with nsd:a.
ImportSettings
Takes an input #ImportMode, a type-0x5 input buffer, a type-0x6 output buffer, no output.
This is only usable with nsd:a.
This also verifies a RSA signature, etc.
SetChangeEnvironmentIdentifierDisabled
Takes an input bool, no output.
This is only usable with nsd:a.
Resolve
Takes a type-0x16 output buffer containing a #Fqdn and a type-0x15 input buffer containing a #Fqdn.
ResolveEx
Takes a type-0x16 output buffer containing a #Fqdn and a type-0x15 input buffer containing a #Fqdn, returns an output u32 "nn::nsd::InnerResult".
The official user-process wrapper code writes the output InnerResult to an output field as a "nn::Result".
GetNasServiceSetting
Takes a type-0x16 output buffer containing a #NasServiceSetting, a type-0x15 input buffer containing a #NasServiceName.
GetNasServiceSettingEx
Takes a type-0x16 output buffer containing a #NasServiceSetting, a type-0x15 input buffer containing a #NasServiceName, returns an output u32 "nn::nsd::InnerResult".
The official user-process wrapper code writes the output InnerResult to an output field as a "nn::Result".
GetNasRequestFqdn
Takes a type-0x16 output buffer containing a #Fqdn.
GetNasRequestFqdnEx
Takes a type-0x16 output buffer containing a #Fqdn, returns an output u32 "nn::nsd::InnerResult".
The official user-process wrapper code writes the output InnerResult to an output field as a "nn::Result".
GetNasApiFqdn
Takes a type-0x16 output buffer containing a #Fqdn.
GetNasApiFqdnEx
Takes a type-0x16 output buffer containing a #Fqdn, returns an output u32 "nn::nsd::InnerResult".
The official user-process wrapper code writes the output InnerResult to an output field as a "nn::Result".
GetCurrentSetting
Takes a type-0x16 output buffer containing a #SaveData.
This is only usable with nsd:a.
WriteTestParameter
Takes a type-0x5 input buffer, no output.
Official sw uses #TestParameter for the buffer.
This is only usable with nsd:a.
ReadTestParameter
Takes a type-0x6 output buffer.
Official sw uses #TestParameter for the buffer.
This is only usable with nsd:a.
ReadSaveDataFromFsForTest
Takes a type-0x16 output buffer containing a #SaveData.
This is only usable with nsd:a.
Requires the nsd!test_mode
setting to be equal to 1 (this doesn't apply with newer sysvers).
Mounts the system save data for bsdsockets as nsdsave
and reads from nsd:/file
to the specified buffer with offset=0 and size=#SaveData size. nsdsave
is then unmounted.
WriteSaveDataToFsForTest
Takes a type-0x15 input buffer containing a #SaveData.
This is only usable with nsd:a. Requires the nsd!test_mode
setting to be equal to 1.
Mounts the system save data for bsdsockets as nsdsave
and writes to nsd:/file
(appending is allowed) using the specified buffer with offset=0 and size=#SaveData size. nsdsave
is then commited and unmounted.
DeleteSaveDataOfFsForTest
No input/output.
This is only usable with nsd:a. Requires the nsd!test_mode
setting to be equal to 1.
Deletes the system save data for bsdsockets.
IsChangeEnvironmentIdentifierDisabled
No input, returns an output bool.
SetWithoutDomainExchangeFqdns
Takes a type-0x5 input buffer containing an array of #Fqdn.
Requires the nsd!test_mode
setting to be equal to 1.
The maximum number of input entries is 2.
GetApplicationServerEnvironmentType
No input. Returns an output ServerEnvironmentType.
This gets the type previously configured by #SetApplicationServerEnvironmentType if available, otherwise it determines the type via the current #EnvironmentIdentifier.
SetApplicationServerEnvironmentType
Takes an input u8 ServerEnvironmentType, no output.
DeleteApplicationServerEnvironmentType
No input/output.
bsd:nu
This is "nn::anif::detail::ISfUserServiceCreator".
This was added with [15.0.0+].
Cmd | Name |
---|---|
0 | #CreateUserService |
CreateUserService
No input. Returns an #ISfUserService.
ISfUserService
This is "nn::anif::detail::ISfUserService".
This was added with [15.0.0+].
Cmd | Name |
---|---|
0 | #Assign |
128 | GetUserInfo |
129 | GetStateChangedEvent |
Assign
Takes an input handle. Returns an #ISfAssignedNetworkInterfaceService.
The handle is the service-session handle for "nn::anif::detail::ISfNetworkInterfaceService".
ISfAssignedNetworkInterfaceService
This is "nn::anif::detail::ISfAssignedNetworkInterfaceService".
This was added with [15.0.0+].
Cmd | Name |
---|---|
0 | #AddSession |
AddSession
Takes an input handle, no output.
The handle is the service-session handle for "nn::anif::detail::ISfNetworkInterfaceService".
LibraryConfigData
This is "nn::socket::sf::LibraryConfigData".
/// Configuration structure for bsdInitalize typedef struct { u32 version; ///< Observed 1 on 2.0 LibAppletWeb, 2 on 3.0. u32 tcp_tx_buf_size; ///< Size of the TCP transfer (send) buffer (initial or fixed). u32 tcp_rx_buf_size; ///< Size of the TCP recieve buffer (initial or fixed). u32 tcp_tx_buf_max_size; ///< Maximum size of the TCP transfer (send) buffer. If it is 0, the size of the buffer is fixed to its initial value. u32 tcp_rx_buf_max_size; ///< Maximum size of the TCP receive buffer. If it is 0, the size of the buffer is fixed to its initial value. u32 udp_tx_buf_size; ///< Size of the UDP transfer (send) buffer (typically 0x2400 bytes). u32 udp_rx_buf_size; ///< Size of the UDP receive buffer (typically 0xA500 bytes). u32 sb_efficiency; ///< Number of buffers for each socket (standard values range from 1 to 8). } LibraryConfigData;
Versions:
System version | Version |
---|---|
[1.0.0-2.3.0] | 0x1 |
[3.0.0-3.0.2] | 0x2 |
[4.0.0-4.1.0] | 0x3 |
[5.0.0-5.1.0] | 0x4 |
[6.0.0-7.0.1] | 0x5 |
[8.0.0-8.1.1] | 0x6 |
[9.0.0-12.1.0] | 0x7 |
[13.0.0-15.0.1] | 0x8 |
[16.0.0+] | 0x9 |
DeleteMode
This is "nn::nsd::DeleteMode".
Value | Description |
---|---|
0 | |
1 |
ImportMode
This is "nn::nsd::ImportMode".
Value | Description |
---|---|
0 | |
1 |
Url
This is "nn::nsd::Url". This is a 0x100-byte struct.
SettingName
This is "nn::nsd::SettingName". This is a 0x100-byte struct.
EnvironmentIdentifier
This is "nn::nsd::EnvironmentIdentifier". This a 0x8-byte struct, containing a string.
DeviceId
This is "nn::nsd::DeviceId". This is a 0x10-byte struct.
Fqdn
This is "nn::nsd::Fqdn". This is a 0x100-byte struct, containing a string.
NasServiceSetting
This is "nn::nsd::NasServiceSetting". This is a 0x108-byte struct.
NasServiceName
This is "nn::nsd::NasServiceName". This is a 0x10-byte struct.
SaveData
This is "nn::nsd::SaveData". This is a 0x12BF0-byte struct.
TestParameter
This is "nn::nsd::detail::TestParameter". This is a 0x80-byte struct.