LDN services: Difference between revisions
(36 intermediate revisions by the same user not shown) | |||
Line 3: | Line 3: | ||
= ldn:m = | = ldn:m = | ||
This is "nn::ldn::detail::IMonitorServiceCreator". | This is "nn::ldn::detail::IMonitorServiceCreator". | ||
This has IPC max_sessions 5. | |||
[20.2.0+] This has max_sessions 6. | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 84: | Line 88: | ||
= ldn:s = | = ldn:s = | ||
This is "nn::ldn::detail::ISystemServiceCreator". | This is "nn::ldn::detail::ISystemServiceCreator". | ||
[18.0.0+] The sdknso uses SessionManager with this, where the additional session-count is 0x3. | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 97: | Line 103: | ||
No input. Returns an [[#ISystemLocalCommunicationService]]. | No input. Returns an [[#ISystemLocalCommunicationService]]. | ||
The user-process closes the ISystemServiceCreator object | The user-process closes the ISystemServiceCreator object once finished with it during initialization. Official sw ignores errors from this cmd. | ||
== CreateClientProcessMonitor == | == CreateClientProcessMonitor == | ||
Line 258: | Line 264: | ||
The sdk user-process func will pass value 1 to the cmd when the input [[#Protocol|Protocol]] is 0/1, 3 is passed directly if specified, otherwise Abort. User-processes use SetProtocol immediately after initializing ldn. | The sdk user-process func will pass value 1 to the cmd when the input [[#Protocol|Protocol]] is 0/1, 3 is passed directly if specified, otherwise Abort. User-processes use SetProtocol immediately after initializing ldn. | ||
[20.0.0+] The ldn initialization functionality in sdknso also uses this with value 1 (NX) eventually after the init cmd was used successfully. | |||
The input is validated, then a vfunc is called. | The input is validated, then a vfunc is called. | ||
Line 286: | Line 294: | ||
Unlike CreateNetworkPrivate, this overwrites the channel field in the [[#NetworkConfig]]. When the cached [[SPL_services#IsDevelopment|IsDevelopment]] value is true, the output from [[Settings_services|GetLdnChannel]] will overwrite that field if the s32 setting value is >=0, otherwise the original value is used. Otherwise when the IsDevelopment field is false (retail), the channel is overwritten with value 0. | Unlike CreateNetworkPrivate, this overwrites the channel field in the [[#NetworkConfig]]. When the cached [[SPL_services#IsDevelopment|IsDevelopment]] value is true, the output from [[Settings_services|GetLdnChannel]] will overwrite that field if the s32 setting value is >=0, otherwise the original value is used. Otherwise when the IsDevelopment field is false (retail), the channel is overwritten with value 0. | ||
This overwrites the u16 field at [[#SecurityConfig]]+0. When the cached [[SPL_services#IsDevelopment|IsDevelopment]] value is false (retail) ([ | This overwrites the u16 field at [[#SecurityConfig]]+0. When the cached [[SPL_services#IsDevelopment|IsDevelopment]] value is false (retail) ([18.0.0+] [[System_Settings|system-setting]] <code>ldn!enable_static_security_mode_configuration</code> is checked for being true instead), value 1 is used ([18.0.0+] value from [[System_Settings|system-setting]] <code>ldn!static_security_mode</code> is used, with fallback to value 1 if the setting is >=0x4), otherwise the original value is used. | ||
[[#GetState|State]] must be 2, this cmd eventually sets the State to value 3. | [[#GetState|State]] must be 2, this cmd eventually sets the State to value 3. | ||
Line 350: | Line 358: | ||
This is identical to [[#ConnectPrivate]] (besides the below), except the data internally passed for [[#SecurityParameter]]/[[#NetworkConfig]] are loaded from the input [[#NetworkInfo]]. | This is identical to [[#ConnectPrivate]] (besides the below), except the data internally passed for [[#SecurityParameter]]/[[#NetworkConfig]] are loaded from the input [[#NetworkInfo]]. | ||
[1.0.0-?] This overwrites the u16 field at [[#SecurityConfig]]+0. When the cached [[SPL_services#IsDevelopment|IsDevelopment]] value is false (retail), value 1 is used, otherwise the used value is: original_field == 0 ? {u16 [[#NetworkInfo]]+0x60} : original_field. [ | [1.0.0-?] This overwrites the u16 field at [[#SecurityConfig]]+0. When the cached [[SPL_services#IsDevelopment|IsDevelopment]] value is false (retail), value 1 is used, otherwise the used value is: original_field == 0 ? {u16 [[#NetworkInfo]]+0x60} : original_field. [18.0.0+] This now uses the same SecurityMode override as [[#CreateNetwork|CreateNetwork]]. | ||
u32 LocalCommunicationVersion>>15 must be 0. | u32 LocalCommunicationVersion>>15 must be 0. | ||
Line 359: | Line 367: | ||
See [[#Connect]]. | See [[#Connect]]. | ||
[1.0.0-?] This overwrites the u16 field at [[#SecurityConfig]]+0. When the cached [[SPL_services#IsDevelopment|IsDevelopment]] value is false (retail), value 1 is used, otherwise the original value is used. [ | [1.0.0-?] This overwrites the u16 field at [[#SecurityConfig]]+0. When the cached [[SPL_services#IsDevelopment|IsDevelopment]] value is false (retail), value 1 is used, otherwise the original value is used. [18.0.0+] This now uses the same SecurityMode override as [[#Connect|Connect]]. | ||
=== Disconnect === | === Disconnect === | ||
Line 371: | Line 379: | ||
This is used immediately after object creation. | This is used immediately after object creation. | ||
With [7.0.0+] [[#InitializeWithVersion|InitializeWithVersion]] is used instead. The cmd impl for Initialize uses [[#InitializeWithVersion|InitializeWithVersion]] with | On old sysvers the cmd impl for User/System are identical, except different params are used for the funcs called internally. | ||
With [7.0.0+] [[#InitializeWithVersion|InitializeWithVersion]] is used instead. The cmd impl for Initialize uses [[#InitializeWithVersion|InitializeWithVersion]] with version=0. | |||
=== Finalize === | === Finalize === | ||
Line 390: | Line 400: | ||
=== InitializeWithVersion === | === InitializeWithVersion === | ||
Takes an input PID, | Takes an input PID, a s32 version, and an u64 pid_placeholder. | ||
The priority is determined by whether the interface is User/System: System = 0x38, User = 0x5A. | |||
It then calls the init func, with the cmd input params and the above priority, returning the Result on failure. | |||
On newer sysvers this then adds an entry for the state array used by [[#RegisterClient|RegisterClient]]. | |||
Lastly the input PID and version are written into state, then this returns. | |||
The init func does the following: | |||
* The PID must be non-zero, and the version must not be negative. The priority must be 0x5A or 0x38. | |||
* An error is returned if state fields are invalid. | |||
* The input PID and version are written into state (a state field is also set to interface == User). | |||
* Lastly, a vfunc is called with the input priority, returning the Result from that. | |||
The | The vfunc does the following: | ||
* On newer sysvers, this uses [[Shared_Database_services|pl:s]] RequestApplicationFunctionAuthorizationByProcessId with the input PID and [[Shared_Database_services|ApplicationFunctionAuthorizationId]] = 2 (SecureLdnLocalCommunication), returning the Result on failure. | |||
* Then a message is sent to a msg-queue with the input priority. | |||
[[# | The handler for the above message does the following: | ||
* When state is already initialized, runs handling for that. An error is also thrown if the input priority is larger than a state field. | |||
* Initializes state, etc. | |||
* Various [[Network_Interface_services|nifm]] funcs are eventually used. The input priority is used to determine the value for [[Network_Interface_services#CreateRequest|nn::nifm::RequestParameters]]: value 0x4 or value 0x8 is used, depending on priority > 0x59. | |||
** Newer versions also handle ldn lan_emulation [[System_Settings|sys-settings]] here. For the above value, when lan_emulation is enabled it uses value 0x17, with 0x18 additionally used for priority <= 0x59. | |||
* The rest is state init, including setting [[#State|State]] to value 1. Then 0 is returned. | |||
On old sysvers the cmd impl for User/System are identical, except different params are used for the funcs called internally. With newer sysvers the cmd impl is now identical. | |||
Version values passed by official sw: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value || SystemVersion | |||
|- | |||
| 0x1 || [7.0.0+] | |||
|- | |||
| 0x2 || [18.0.0+] | |||
|- | |||
| 0x3 || [19.0.0+] | |||
|- | |||
| 0x4 || [20.0.0+] | |||
|} | |||
=== InitializeWithPriority === | === InitializeWithPriority === | ||
Takes an input PID, | Takes an input PID, a s32 version, a s32 priority, and an u64 pid_placeholder. | ||
This is similar to [[#InitializeWithVersion|InitializeWithVersion]] | This is similar to [[#InitializeWithVersion|InitializeWithVersion]]. The input priority is passed directly to the init func which is called here, instead of determining it from whether the interface is User/System. | ||
Official sw passes input value 0x38 for the priority as the default, when the user doesn't specify the priority. | |||
=== EnableActionFrame === | === EnableActionFrame === | ||
Line 419: | Line 463: | ||
=== SendActionFrame === | === SendActionFrame === | ||
Takes a type-0x21 input buffer, two input [[#MacAddress]], two input s16s ('''Band''' and '''ChannelNumber''') and an input [[#MessageFlagSet]]. No output. | Takes a type-0x21 input buffer, two input [[#MacAddress]], two input s16s ('''Band''' and '''ChannelNumber''') and an input [[#MessageFlagSet]]. No output. | ||
[20.0.0+] The input s16s were replaced with a single u16, which has the same format as [[#SetHomeChannel|SetHomeChannel]]. | |||
The first [[#MacAddress]] is the destination, the second [[#MacAddress]] is the Bssid. | |||
The ChannelNumber must be non-zero. | |||
[[#State|State]] must be 3-4 (AccessPointCreated/Station). | [[#State|State]] must be 3-4 (AccessPointCreated/Station). | ||
=== RecvActionFrame === | |||
Takes a type-0x22 output buffer and an input [[#MessageFlagSet]]. Returns two output [[#MacAddress]], two output s16s ('''Band''' and '''ChannelNumber'''), an output u32 '''Size''', and an output s32 '''LinkLevel'''. | |||
[20.0.0+] The output s16s were replaced with a single u16, which has the same format as [[#SetHomeChannel|SetHomeChannel]]. | |||
[[#EnableActionFrame|EnableActionFrame]] must be used prior to this. | [[#EnableActionFrame|EnableActionFrame]] must be used prior to this. | ||
Line 432: | Line 482: | ||
Takes two input s16s '''Band''' and '''ChannelNumber'''. No output. | Takes two input s16s '''Band''' and '''ChannelNumber'''. No output. | ||
[20.0.0+] Now takes a | [20.0.0+] Now takes an input u16 instead of two s16s, merging the two params. Bitmask 0x3FF (low 10-bits) is the ChannelNumber, while the remaining upper 6-bits is the Band. The Band is used as an array index to load the actual Band for passing to a func. Only the following Band input is valid, others return 0x0/0xFFFF: 2 - > 2400, 5 -> 5000, 6 -> 6000. | ||
On NX Band must be ([20.0.0+] converted Band from the above array) 50 ([20.0.0+] 5000) or 24 ([20.0.0+] 2400). | |||
The ChannelNumber must be non-zero. | |||
The [[#State|State]] must be Station. | |||
sdknso uses the input channel to convert to the input needed by the cmd. | |||
=== SetTxPower === | === SetTxPower === | ||
Takes an input s16 '''Power'''. No output. | Takes an input s16 '''Power'''. No output. | ||
The input must be 0x0..0xFF. | |||
A state field must be non-zero. | |||
The [[#State|State]] must be 2-5 (AccessPoint*/Station*). | |||
=== ResetTxPower === | === ResetTxPower === | ||
No input/output. | No input/output. | ||
The same state field checked by [[#SetTxPower|SetTxPower]] must be non-zero. The [[#State|State]] check is also the same as [[#SetTxPower|SetTxPower]]. | |||
== IClientProcessMonitor == | == IClientProcessMonitor == | ||
Line 451: | Line 517: | ||
| 0 || RegisterClient | | 0 || RegisterClient | ||
|} | |} | ||
=== RegisterClient === | |||
Takes an input PID and an u64 pid_placeholder. | |||
[18.0.0+] [[#CreateClientProcessMonitor|CreateClientProcessMonitor]] and RegisterClient are used by sdknso at the end of the ldn initialization functionality. | |||
If the objptr in IClientProcessMonitor state is already set from using this cmd previously, this just returns 0. | |||
This goes through global state to locate an entry with a matching PID, if none found 0 is returned. The objptr from the state entry is loaded, if NULL this returns 0. This obj is then incref'd and written into the IClientProcessMonitor state. When PID is 0, 0 is returned. It then locates the above state entry again with a matching PID, clearing the entry which matches. Lastly 0 is returned. | |||
The initialization [[#InitializeWithPriority|cmds]] adds an entry to the above global state. | |||
= ldn:u = | = ldn:u = | ||
This is "nn::ldn::detail::IUserServiceCreator". | This is "nn::ldn::detail::IUserServiceCreator". | ||
[18.0.0+] The sdknso uses SessionManager with this, where the additional session-count is 0x3. | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 467: | Line 546: | ||
Returns an [[#IUserLocalCommunicationService]]. | Returns an [[#IUserLocalCommunicationService]]. | ||
The user-process closes the IUserServiceCreator object | The user-process closes the IUserServiceCreator object once finished with it during initialization. Official sw ignores errors from this cmd. | ||
== IUserLocalCommunicationService == | == IUserLocalCommunicationService == | ||
This is "nn::ldn::detail::IUserLocalCommunicationService". | This is "nn::ldn::detail::IUserLocalCommunicationService". | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 534: | Line 611: | ||
| 304 || [[#Disconnect|Disconnect]] | | 304 || [[#Disconnect|Disconnect]] | ||
|- | |- | ||
| 400 || [[# | | 400 || [[#Initialize_2|Initialize]] | ||
|- | |- | ||
| 401 || [[# | | 401 || [[#Finalize_2|Finalize]] | ||
|- | |- | ||
| 402 || [7.0.0+] [[# | | 402 || [7.0.0+] [[#InitializeWithVersion|InitializeWithVersion]] | ||
|- | |- | ||
| 403 || [19.0.0+] [[# | | 403 || [19.0.0+] [[#SetOperationMode|SetOperationMode]] | ||
|- | |- | ||
| 500 || [18.0.0+] [[#EnableActionFrame|EnableActionFrame]] | | 500 || [18.0.0+] [[#EnableActionFrame|EnableActionFrame]] | ||
Line 556: | Line 633: | ||
| 601 || [18.0.0+] [[#ResetTxPower|ResetTxPower]] | | 601 || [18.0.0+] [[#ResetTxPower|ResetTxPower]] | ||
|} | |} | ||
= ndd = | = ndd = | ||
Line 958: | Line 1,012: | ||
= NodeInfo = | = NodeInfo = | ||
This is "nn::ldn::NodeInfo". | This is "nn::ldn::NodeInfo". | ||
The first node in the nodes array is always the AccessPoint (NodeId 0x0). NodeId is the index of the node in the nodes array. | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 975: | Line 1,031: | ||
| 0xC || 0x21 || UserName | | 0xC || 0x21 || UserName | ||
|- | |- | ||
| 0x2D || 0x1 || [ | | 0x2D || 0x1 || [19.0.0+] Platform? (0 = NX, 1 = Ounce) | ||
|- | |- | ||
| 0x2E || 0x2 || LocalCommunicationVersion | | 0x2E || 0x2 || LocalCommunicationVersion | ||
Line 1,013: | Line 1,069: | ||
| 0xC || 0x4 || Reserved | | 0xC || 0x4 || Reserved | ||
|} | |} | ||
* LocalCommunicationId: [[#CreateNetwork|CreateNetwork]], [[#CreateNetworkPrivate|CreateNetworkPrivate]], [[#Connect|Connect]], [[#ConnectPrivate|ConnectPrivate]] (also [[#ScanFilter|ScanFilter]] when enabled with the flag): When -1, this is overwritten with the first LocalCommunicationId from the user-process [[NACP]], if loading fails value 0 is written instead. Otherwise when not -1, if [[NACP]] loading is successful, this field must match one of the LocalCommunicationIds from there. | |||
* SceneId: Arbitrary user data, this can be used for filtering with [[#ScanFilter|ScanFilter]] for example. | |||
= SessionId = | = SessionId = | ||
This is "nn::ldn::SessionId". | This is "nn::ldn::SessionId". | ||
This is used to generate/overwrite the Ssid when needed. | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 1,119: | Line 1,180: | ||
This is "nn::ldn::ScanFilter". This is a 0x60-byte struct with 8-byte alignment. | This is "nn::ldn::ScanFilter". This is a 0x60-byte struct with 8-byte alignment. | ||
sdknso copies the input ScanFilter to a tmp struct on stack, which is then used with the cmd. | sdknso copies the input ScanFilter to a tmp struct on stack (with [[#ScanFilterFlag|Flag]] masking), which is then used with the cmd. sdknso only copies Bssid with [[#ScanPrivate|ScanPrivate]], with [[#Scan|Scan]] it also masks out the [[#ScanFilterFlag|Flag]] for Bssid. | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 1,139: | Line 1,200: | ||
| 0x5C || 0x4 || [[#ScanFilterFlag|Flag]] | | 0x5C || 0x4 || [[#ScanFilterFlag|Flag]] | ||
|} | |} | ||
Each [[#ScanFilterFlag|Flag]] bit when set enables using the corresponding ScanFilter data. This is usually a compare with the ScanFilter data and the internal [[#NetworkInfo|NetworkInfo]] data. | |||
* NetworkType: (ScanFilter_NetworkType & NetworkInfo_NetworkType) must be non-zero. | |||
* Ssid: The length fields must match, then memcmp is used. | |||
The filtering func also handles validating the Band/Channel, however these fields are internal only and are not exposed in the user ScanFilter. | |||
= ScanFilterFlag = | = ScanFilterFlag = | ||
Line 1,278: | Line 1,346: | ||
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. | ||
sdknso copies the input UserConfig to a tmp struct on stack, which is then used with the cmd. | 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. | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 1,286: | Line 1,354: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || 0x21 || UserName (NUL-terminated string for the user | | 0x0 || 0x21 || UserName (NUL-terminated string for the user name) | ||
|- | |- | ||
| 0x21 || 0xF || Reserved | | 0x21 || 0xF || Reserved | ||
|} | |} | ||
Line 1,412: | Line 1,480: | ||
| 0x3C || 0x2 || SecurityMode | | 0x3C || 0x2 || SecurityMode | ||
|- | |- | ||
| 0x3E || 0x2 || PassphraseSize | | 0x3E || 0x2 || PassphraseSize (Must be 0x10-0x40) | ||
|- | |- | ||
| 0x40 || 0x40 || Passphrase | | 0x40 || 0x40 || Passphrase | ||
|} | |} | ||
SecurityMode must be 1-2. The same SecurityMode override functionality from elsewhere is used later with this. | |||
The same LocalCommunicationId override/validation from elsewhere is used with the input as well. | |||
= MessageFlagSet = | = MessageFlagSet = | ||
Line 1,430: | Line 1,502: | ||
| 0 || | | 0 || | ||
|} | |} | ||
[[#SendActionFrame|SendActionFrame]]/[[#RecvActionFrame|RecvActionFrame]] handles bit0 the same way as the MessageFlag with lp2p [[#SendToOtherGroup|SendToOtherGroup]]/[[#RecvFromOtherGroup|RecvFromOtherGroup]]. | |||
= MacAddress = | = MacAddress = | ||
Line 1,611: | Line 1,685: | ||
| 0x4 || 0x1 || [6.0.0+] High u8 for the size. | | 0x4 || 0x1 || [6.0.0+] High u8 for the size. | ||
|- | |- | ||
| 0x5 || 0x1 || [ | | 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]] 3). | ||
|- | |- | ||
| 0x6 || 0x2 || Unused, zeros. | | 0x6 || 0x2 || Unused, zeros. | ||
Line 1,653: | Line 1,727: | ||
| 0x20 || 0x2 || Big-endian LocalCommunicationVersion. Byte-swapped by the AccessPoint then copied into state. [?+] This is now ignored. | | 0x20 || 0x2 || Big-endian LocalCommunicationVersion. Byte-swapped by the AccessPoint then copied into state. [?+] This is now ignored. | ||
|- | |- | ||
| 0x22 || 0x1 || [ | | 0x22 || 0x1 || [19.0.0+] [[#NodeInfo|NodeInfo]] +0x2D. Copied into state by the AccessPoint. On NX the Station always sets this to 0 in the sent payload-data. | ||
|- | |- | ||
| 0x23 || 0x1D || Zeros, unused by the AccessPoint. | | 0x23 || 0x1D || Zeros, unused by the AccessPoint. | ||
Line 1,670: | Line 1,744: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || | | 0x0 || 0x1 || | ||
|- | |||
| 0x1 || 0x3F || Zeros. [6.0.0-?] Only included in the frame if it's enabled (+0x0 [[#AuthVersion]] >= 3). Unused by the Station. | |||
|- | |- | ||
| 0x40 || 0x44 || [6.0.0-?] Only included in the frame if it's enabled (+0x0 [[#AuthVersion]] >= 3). Unused by the Station. | | 0x40 || 0x44 || [6.0.0-?] Only included in the frame if it's enabled (+0x0 [[#AuthVersion]] >= 3). Unused by the Station. | ||
Line 1,692: | Line 1,768: | ||
| 3 || [6.0.0+] | | 3 || [6.0.0+] | ||
|- | |- | ||
| 4 || | | 4 || [19.0.0+] | ||
|} | |} | ||
Line 1,729: | Line 1,805: | ||
| 0x20 || 0x1 || [[#AuthVersion]]. Copied to [[#NetworkInfo]]+0x63. When comparing with a previous frame is enabled, this must match the value from the previous frame. | | 0x20 || 0x1 || [[#AuthVersion]]. Copied to [[#NetworkInfo]]+0x63. When comparing with a previous frame is enabled, this must match the value from the previous frame. | ||
|- | |- | ||
| 0x21 || 0x1 || Encryption type: 1 = plaintext, 2 = AES-128-CTR, 3 = AES-128-GCM, {frames with other values are ignored by [[#Scan]]/[[#ScanPrivate]]}. Must match the type which is currently being used: with [[#Scan]]/[[#ScanPrivate]] this is determined via this field, otherwise [[#SecurityConfig]] is used to determine this. | | 0x21 || 0x1 || Encryption type: 1 = plaintext, 2 = AES-128-CTR, [20.0.0+] 3 = AES-128-GCM, {frames with other values are ignored by [[#Scan]]/[[#ScanPrivate]]}. Must match the type which is currently being used: with [[#Scan]]/[[#ScanPrivate]] this is determined via this field, otherwise [[#SecurityConfig]] is used to determine this. | ||
|- | |- | ||
| 0x22 || 0x2 || Big-endian u16 size for the data starting at +0x48 (+0x38 with EncryptionType3), and must match {total frame size relative to +0x0 above} - {header_size}. | | 0x22 || 0x2 || Big-endian u16 size for the data starting at +0x48 (+0x38 with EncryptionType3), and must match {total frame size relative to +0x0 above} - {header_size}. | ||
Line 1,743: | Line 1,819: | ||
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. | ||
Originally [[#Scan]]/[[#ScanPrivate]] used the EncryptionType field to determine encryption handling. With [18.0.0+] these now set an internal SecurityMode field to 0 (Any) initially, then later uses the same SecurityMode override as [[#CreateNetwork|CreateNetwork]]. The internal SecurityMode field is used to determine encryption handling: Any uses the EncryptionType field like before. With non-zero the encryption handling is determined as required by the SecurityMode. | |||
The content data at +{above_header_size} follows, which has the size specified above (which must be >=0x500 with EncryptionType1-2), where all fields are big-endian. For EncryptionType1-2: | The content data at +{above_header_size} follows, which has the size specified above (which must be >=0x500 with EncryptionType1-2), where all fields are big-endian. For EncryptionType1-2: | ||
Line 1,828: | Line 1,906: | ||
| 0xA || 0x1 || bool IsConnected | | 0xA || 0x1 || bool IsConnected | ||
|- | |- | ||
| 0xB || 0x1 || [ | | 0xB || 0x1 || [19.0.0+] [[#NodeInfo|NodeInfo]] +0x2D | ||
|- | |- | ||
| 0xC || 0x20 || First 0x20-bytes of [[#UserConfig]]. | | 0xC || 0x20 || First 0x20-bytes of [[#UserConfig]]. | ||
Line 1,859: | Line 1,937: | ||
=== ActionFrame2 === | === ActionFrame2 === | ||
The Action frames used by [[#RecvActionFrame|RecvActionFrame]] have the following structure: | The Action frames used by [[#SendActionFrame|SendActionFrame]]/[[#RecvActionFrame|RecvActionFrame]] have the following structure: | ||
* "Fixed parameters": | * "Fixed parameters": | ||
** "Category code: Vendor Specific (127)" | ** "Category code: Vendor Specific (127)" | ||
Line 1,875: | Line 1,953: | ||
| 0x2 || 0x2 || Protocol ID, must match big-endian 0x0102. | | 0x2 || 0x2 || Protocol ID, must match big-endian 0x0102. | ||
|- | |- | ||
| 0x4 || 0x2 || | | 0x4 || 0x2 || 00 00 | ||
|- | |- | ||
| 0x6 || 0x2 || | | 0x6 || 0x2 || 00 00 | ||
|} | |} | ||
Line 1,906: | Line 1,984: | ||
The 0xC-byte IV for AES-128-GCM is the raw 4-bytes from the above Counter, with the rest cleared to zeroes. The encrypted data is at +0x30, with the remaining frame size. The AAD is the 0x20-bytes at +0x0. | The 0xC-byte IV for AES-128-GCM is the raw 4-bytes from the above Counter, with the rest cleared to zeroes. The encrypted data is at +0x30, with the remaining frame size. The AAD is the 0x20-bytes at +0x0. | ||
The key is derived similar to the regular action-frame key (same KeySource), except: the Generation is always [[17.0.0|0x11]], with the following data for hashing: {big-endian LocalCommunicationId} {+0x10 size 0x10-bytes} {[[#ActionFrameSettings]] Passphrase with the specified PassphraseSize}. | |||
The data payload is the data buffer for [[#SendActionFrame|SendActionFrame]]/[[#RecvActionFrame|RecvActionFrame]]. | |||
== lp2p == | == lp2p == |