LDN services: Difference between revisions
| (17 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
LDN handles all local network communication. | LDN handles all local network communication. | ||
There's 2 IPC handler threads for all ldn:* services. | |||
= ldn:m = | = ldn:m = | ||
| Line 45: | Line 47: | ||
=== GetState === | === GetState === | ||
No input, returns an output u32. | No input, returns an output [[#State|u32]]. | ||
sdknso implements this by <code>return</code>ing the u32, with 0 being returned on error. | sdknso implements this by <code>return</code>ing the u32, with 0 being returned on error. | ||
| Line 88: | Line 90: | ||
= ldn:s = | = ldn:s = | ||
This is "nn::ldn::detail::ISystemServiceCreator". | This is "nn::ldn::detail::ISystemServiceCreator". | ||
This has IPC max_sessions 5. | |||
[18.0.0+] The sdknso uses SessionManager with this, where the additional session-count is 0x3. | [18.0.0+] The sdknso uses SessionManager with this, where the additional session-count is 0x3. | ||
| Line 203: | Line 207: | ||
=== GetNetworkInfo === | === GetNetworkInfo === | ||
Takes a type-0x1A output buffer containing a [[#NetworkInfo]]. | Takes a type-0x1A output buffer containing a [[#NetworkInfo]]. | ||
[[#GetState|State]] must be 3 or 5. | |||
=== GetIpv4Address === | === GetIpv4Address === | ||
| Line 259: | Line 265: | ||
=== SetProtocol === | === SetProtocol === | ||
Takes an input u32, no output. | Takes an input [[#Protocol|u32]], no output. | ||
This cmd was implemented with [20.0.0+], prior to that this just returned an error. | This cmd was implemented with [20.0.0+], prior to that this just returned an error. | ||
| Line 269: | Line 275: | ||
The input is validated, then a vfunc is called. | The input is validated, then a vfunc is called. | ||
The cmd_input must be non-zero. BIT(cmd_input) must be set in a state-field, otherwise a separate Result is returned. | The cmd_input must be non-zero. BIT(cmd_input) must be set in a state-field, otherwise a separate Result is returned. This is a permission [[#Protocol|bitmask]] which originates from the ldn:* service object being used. | ||
The vfunc sends a message to another thread with the input u32 as the param, and returns the response from that. | The vfunc sends a message to another thread with the input u32 as the param, and returns the response from that. | ||
The thread msg-queue-handler (besides other validation) uses the input param to select what values to write to state fields. | The thread msg-queue-handler (besides other validation) uses the input param to select what values to write to state fields. On NX only input value 1 or 3 is allowed, with an error being thrown otherwise. The previously mentioned validation includes verifying that [[#GetState|State]] is Initialized. | ||
=== OpenAccessPoint === | === OpenAccessPoint === | ||
| Line 470: | Line 474: | ||
The ChannelNumber must be non-zero. | The ChannelNumber must be non-zero. | ||
[[#State|State]] must be 3- | [[#State|State]] must be 3-5 (AccessPointCreated/Station/StationConnected). | ||
=== RecvActionFrame === | === RecvActionFrame === | ||
| Line 531: | Line 535: | ||
= ldn:u = | = ldn:u = | ||
This is "nn::ldn::detail::IUserServiceCreator". | This is "nn::ldn::detail::IUserServiceCreator". | ||
This has IPC max_sessions 3. | |||
[18.0.0+] The sdknso uses SessionManager with this, where the additional session-count is 0x3. | [18.0.0+] The sdknso uses SessionManager with this, where the additional session-count is 0x3. | ||
[S2] There appears to be 2 ldn:u services, this appears to be for having separate [[#Protocol|Protocol]] permissions for NX and Ounce games. The Creator object has the same vtable for both of these. However the vtable for IUserLocalCommunicationService appears to be larger even with NX, which likely indicates there's new commands? There also appears to be 4 additional max-sessions allocated to ldn*, this is probably for one of these ldn:u services? | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
| Line 1,345: | Line 1,353: | ||
= UserConfig = | = UserConfig = | ||
This is "nn::ldn::UserConfig". This is a 0x30-byte struct with 1-byte alignment. | This is "nn::ldn::UserConfig". This is a 0x30-byte struct with 1-byte alignment. | ||
An error is thrown if UserName+0x20 is non-zero. | |||
sdknso copies the input UserConfig to a tmp struct on stack, which is then used with the cmd. Only the first 0x20-bytes are copied, with the rest cleared. | sdknso copies the input UserConfig to a tmp struct on stack, which is then used with the cmd. Only the first 0x20-bytes are copied, with the rest cleared. | ||
| Line 1,454: | Line 1,464: | ||
|- | |- | ||
| 1 || NX | | 1 || NX | ||
|- | |||
| 2 || [S2] | |||
|- | |- | ||
| 3 || (NXAndOunce?) | | 3 || (NXAndOunce?) | ||
|- | |||
| 4 || [S2] | |||
|} | |} | ||
The Initialize* cmds configure state the same as using [[#SetProtocol|SetProtocol]] with Protocol NX. | The Initialize* cmds configure state the same as using [[#SetProtocol|SetProtocol]] with Protocol NX. | ||
There | There appears to be S2-only values which enables using Ounce-only keys. The following uses new Ounce-only keys (with S2 hosting): | ||
* In-game ldn-usage for a S2-only Application. | * In-game ldn-usage for a S2-only Application. | ||
* Local-game-update with a S2-only Application. | * Local-game-update with a S2-only Application. | ||
* Local-game-update for a S1-game which has a Nintendo Switch 2 Edition available, even without the S2-Edition being installed. | * Local-game-update for a S1-game which has a Nintendo Switch 2 Edition available, even without the S2-Edition being installed. | ||
There's system-titles which [[20.0.0|use]] SetProtocol. While there's game(s) which use SetProtocol, there's no known (?) games using Protocol3 (excluding GameShare which is system). | |||
[S2] Protocol2 and Protocol4 appear to be identical to Protocol3 except for using [[SPL_services|Ounce]] keys (?). It's unknown exactly which Protocol uses which [[SPL_services|Generation]], though presumably 2/4 is Generation 0x0/0x1? lcs (local-content-share) uses Generation 0x1, while Mario Kart World uses 0x0. | |||
[S2] Keys are generated by passing the SHA256 hash as the KeySource to the relevant [[SPL_services|spl:ldn]] command with the above Generation, with the full hash being passed to the Ounce cmds. Only the first 0x10-bytes of the output key is used, since AES-128 is used even with Ounce. | |||
On NX, the Protocol [[#SetProtocol|permission-bitmask]] is always set to 0xA (1 and 3). On Ounce, all services have this set to 0x1E, except for one which has it set to 0xA (which is likely the one for S1-compat). 0x1E allows additional protocol values 2 and 4. | |||
= ActionFrameSettings = | = ActionFrameSettings = | ||
| Line 1,652: | Line 1,674: | ||
After Authentication the Station will scan for another [[#ActionFrame]], with frame-comparision enabled with the above frame (frame must have been updated since the previous scan). The Station locates the index for a [[#MacAddress|MacAddress]] matching itself in the [[#NetworkInfo]] [[#NodeInfo|NodeInfo]] array (the entry for the AccessPoint is skipped), throwing an error if not found. After validating the LocalCommunicationVersion, it proceeds to handle ARP setup below. | After Authentication the Station will scan for another [[#ActionFrame]], with frame-comparision enabled with the above frame (frame must have been updated since the previous scan). The Station locates the index for a [[#MacAddress|MacAddress]] matching itself in the [[#NetworkInfo]] [[#NodeInfo|NodeInfo]] array (the entry for the AccessPoint is skipped), throwing an error if not found. After validating the LocalCommunicationVersion, it proceeds to handle ARP setup below. | ||
This does not use DHCP, each node on the network has to manually setup | This does not use DHCP, each node on the network has to manually setup IP-config with the [[#NodeInfo|NodeInfo]] array in [[#NetworkInfo]]. [?+] After the client is [[#EthFrame|authenticated]] ARP may be used in some cases however. | ||
At this point standard sockets can be used over Data frames. | At this point standard sockets can be used over Data frames. | ||
| Line 1,685: | Line 1,707: | ||
| 0x4 || 0x1 || [6.0.0+] High u8 for the size. | | 0x4 || 0x1 || [6.0.0+] High u8 for the size. | ||
|- | |- | ||
| 0x5 || 0x1 || [20.0.0+] AuthEncryptionType, must match the type being used by the [[#Protocol|Protocol]]. 0 = plaintext ([[#Protocol|Protocol]] NX), 1 = AES-128-GCM ([[#Protocol|Protocol]] | | 0x5 || 0x1 || [20.0.0+] AuthEncryptionType, must match the type being used by the [[#Protocol|Protocol]]. 0 = plaintext ([[#Protocol|Protocol]] NX), 1 = AES-128-GCM ([[#Protocol|Protocol]] non-NX). | ||
|- | |- | ||
| 0x6 || 0x2 || Unused, zeros. | | 0x6 || 0x2 || Unused, zeros. | ||
| Line 1,744: | Line 1,766: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || 0x1 || | | 0x0 || 0x1 || Unused, always set to 0. [S2] This is usually set to value 1? | ||
|- | |- | ||
| 0x1 || 0x3F || Zeros. [6.0.0-?] Only included in the frame if it's enabled (+0x0 [[#AuthVersion]] >= 3). Unused by the Station. | | 0x1 || 0x3F || Zeros. [6.0.0-?] Only included in the frame if it's enabled (+0x0 [[#AuthVersion]] >= 3). Unused by the Station. | ||
| Line 1,754: | Line 1,776: | ||
===== AuthVersion ===== | ===== AuthVersion ===== | ||
Must be 0x1-0xF (< | Must be 0x1-0xF (<0x10 with newer versions). | ||
[?+] When the AccessPoint is handling the [[#Authentication|Authentication]] EthFrame, the AuthVersion must be >=1 for [[#Protocol|Protocol]] NX, and >=4 for [[#Protocol|Protocol]] 3. | [?+] When the AccessPoint is handling the [[#Authentication|Authentication]] EthFrame, the AuthVersion must be >=1 for [[#Protocol|Protocol]] NX, and >=4 for [[#Protocol|Protocol]] 3. | ||
| Line 1,816: | Line 1,838: | ||
|} | |} | ||
Using EncryptionType3 outside of [[#Scan]]/[[#ScanPrivate]] is enabled with [[#Protocol|Protocol]] | Using EncryptionType3 outside of [[#Scan]]/[[#ScanPrivate]] is enabled with [[#Protocol|Protocol]] non-NX. | ||
When encryption is enabled, the encrypted data is at +0x28 (+0x38 with EncryptionType3) with size {remaining frame size}. The key is derived from the raw 0x20-bytes at +0x0. The CTR/IV is {raw Counter above without byte-swap}, with the rest cleared to zeros. The AAD for AES-128-GCM is at +0x0 size 0x28-bytes. | When encryption is enabled, the encrypted data is at +0x28 (+0x38 with EncryptionType3) with size {remaining frame size}. The key is derived from the raw 0x20-bytes at +0x0. The CTR/IV is {raw Counter above without byte-swap}, with the rest cleared to zeros. The AAD for AES-128-GCM is at +0x0 size 0x28-bytes. | ||
| Line 1,867: | Line 1,889: | ||
| 0x0 || 0x10 || [[#NetworkInfo]]+0x50 | | 0x0 || 0x10 || [[#NetworkInfo]]+0x50 | ||
|- | |- | ||
| 0x10 || 0x8 || [[#NetworkInfo]]+0x478 | | 0x10 || 0x8 || [[#NetworkInfo]]+0x478 [S2] The Station seems to verify that this is 0 when the Challenge is unused (ldn:s)? Throws an error if set before connecting to an [[#Protocol|Ounce]] network. | ||
|- | |- | ||
| 0x18 || 0x1 || [[#NetworkInfo]]+0x60 | | 0x18 || 0x1 || [[#NetworkInfo]]+0x60 | ||
| Line 2,138: | Line 2,160: | ||
|- | |- | ||
| 0x0 || {remaining size} || Plaintext user-data. | | 0x0 || {remaining size} || Plaintext user-data. | ||
|} | |||
= Notes = | |||
The following services are accessible to ldn: | |||
* arp:r, bsd:s, btm, es, fatal:u, ifcfg, lm, nifm:s, pl:s, set:sys, spl:mig, wlan | |||
[S2] Access to btm and spl:mig were replaced with bt:sys and spl:ldn. | |||
[S2] Various objects/state have the same size/layout as S1, generally?(Other than IPC-related differences) There's also stack differences. | |||
== Code-region Memory Layout == | |||
=== S2 20.5.0 === | |||
This is the codebin-region layout for S2 ldn 20.5.0, exact starting version unknown. BuildId is "DC456FA4...". | |||
The on-NX note is for the equivalent memregion location/size, memregion-size/contents compared to NX may vary. | |||
Total size is 0x24F000-bytes. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Permissions | |||
! Description | |||
|- | |||
| 0x0 || 0xE1000 || --X || .text | |||
|- | |||
| 0xE1000 || 0x3D000 || R-- || RO-region | |||
|- | |||
| 0x11E000 || 0x3A000 || RW || On NX this is at 0xEF000. The main ExpHeap is at +0x2000, on NX it's at +0x1000. | |||
|- | |||
| 0x158000 || 0x8000 || non-RW || On NX this is at 0x123000. | |||
|- | |||
| 0x160000 || 0x8000 || RW || On NX this is at 0x12B000. | |||
|- | |||
| 0x168000 || 0xF000 || non-RW || On NX this is at 0x139000. | |||
|- | |||
| 0x177000 || 0x3000 || RW || On NX this is at 0x13F000. | |||
|- | |||
| 0x17A000 || 0x24000 || non-RW || On NX this is at 0x14B000. | |||
|- | |||
| 0x19E000 || 0x4E000 || RW || On NX this is at 0x16F000. | |||
|- | |||
| 0x1EC000 || 0x2000 || -- || On NX this is at 0x1BD000. | |||
|- | |||
| 0x1EE000 || 0x2000 || {accessible} || On NX this is at 0x1BF000. | |||
|- | |||
| 0x1EF000 || 0x5000 || -- || On NX this is at 0x1E2000. | |||
|- | |||
| 0x1F4000 || 0x21000 || {accessible} || On NX this is at 0x1EA000. | |||
|- | |||
| 0x218000 || 0x8000 || -- || | |||
|- | |||
| 0x220000 || 0x2F000 || {accessible} | |||
|} | |} | ||
[[Category:Services]] | [[Category:Services]] | ||