Changes

Jump to navigation Jump to search
4,369 bytes added ,  19:35, 22 March 2022
no edit summary
Line 125: Line 125:  
|-
 
|-
 
| 104 || [5.0.0+] [[#SetWirelessControllerRestriction]]
 
| 104 || [5.0.0+] [[#SetWirelessControllerRestriction]]
 +
|-
 +
| 105 || [13.1.0+] SetBluetoothAudioDeviceConnectableMode
 
|-
 
|-
 
| 200 || [[#OpenAccessPoint]]
 
| 200 || [[#OpenAccessPoint]]
Line 445: Line 447:  
|-
 
|-
 
| 104 || [5.0.0+] [[#SetWirelessControllerRestriction]]
 
| 104 || [5.0.0+] [[#SetWirelessControllerRestriction]]
 +
|-
 +
| 105 || [13.1.0+] SetBluetoothAudioDeviceConnectableMode
 
|-
 
|-
 
| 200 || [[#OpenAccessPoint]]
 
| 200 || [[#OpenAccessPoint]]
Line 569: Line 573:     
= lp2p:app, lp2p:sys =
 
= lp2p:app, lp2p:sys =
These are "nn::lp2p::detail::INetworkServiceCreator".
+
These are "nn::lp2p::detail::ISfServiceCreator".
    
These were added with [9.0.0+].
 
These were added with [9.0.0+].
   −
lp2p:app is used by [[Mario Kart Live: Home Circuit]].
+
lp2p:app is used by [[Mario Kart Live: Home Circuit]]. lp2p:sys is used by [[Album_Applet|LibraryAppletPhotoViewer]] with [11.0.0+].
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 585: Line 589:     
== CreateNetworkService ==
 
== CreateNetworkService ==
Takes an input u32, an u64 pid_reserved, a PID, returns an output [[#INetworkService]].
+
Takes a PID-descriptor, a reserved input u64 and an input u32. Returns an output [[#ISfService]].
    
The input u32 must be value 0x1.
 
The input u32 must be value 0x1.
    
== CreateNetworkServiceMonitor ==
 
== CreateNetworkServiceMonitor ==
Takes an input u64 pid_reserved, a PID, returns an output [[#INetworkServiceMonitor]].
+
Takes a PID-descriptor and a reserved input u64. Returns an output [[#ISfServiceMonitor]].
   −
== INetworkService ==
+
== ISfService ==
This is "nn::lp2p::detail::INetworkService".
+
This is "nn::lp2p::detail::ISfService".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 611: Line 615:  
| [9.0.0-9.0.1] 288 || [[#GetGroupInfo]]
 
| [9.0.0-9.0.1] 288 || [[#GetGroupInfo]]
 
|-
 
|-
| [9.0.0-9.0.1] 296 || [[#Join]]
+
| [9.0.0-9.0.1] 296 || [[#GetGroupInfo2]]
 
|-
 
|-
 
| [9.0.0-9.0.1] 304 || [[#GetGroupOwner]]
 
| [9.0.0-9.0.1] 304 || [[#GetGroupOwner]]
Line 617: Line 621:  
| [9.0.0-9.0.1] 312 || [[#GetIpConfig]]
 
| [9.0.0-9.0.1] 312 || [[#GetIpConfig]]
 
|-
 
|-
| [9.0.0-9.0.1] 320 || [[#Leave]]
+
| [9.0.0-9.0.1] 320 || [[#GetLinkLevel]]
 
|-
 
|-
 
| 512 || [[#Scan]]
 
| 512 || [[#Scan]]
Line 633: Line 637:  
| 1552 || [[#AddAcceptableGroupId]]
 
| 1552 || [[#AddAcceptableGroupId]]
 
|-
 
|-
| 1560 || [9.1.0+] [[#RemoveAcceptableGroupId]]
+
| 1560 || [9.1.0+] [[#ClearAcceptableGroupId]]
 
|}
 
|}
   Line 644: Line 648:     
=== Scan ===
 
=== Scan ===
Takes a type-0x19 input buffer containing a [[#GroupInfo]], a type-0x22 output buffer containing an array of [[#ScanResult]], returns an output s32 total_out.
+
Takes a type-0x19 input buffer containing a [[#GroupInfo]] and a type-0x22 output buffer containing an array of [[#ScanResult]]. Returns an output s32 '''TotalOut'''.
    
=== CreateGroup ===
 
=== CreateGroup ===
Takes a type-0x31 input buffer containing a [[#GroupInfo]], no output.
+
Takes a type-0x31 input buffer containing a [[#GroupInfo]]. No output.
    
[[Mario Kart Live: Home Circuit|mklive]] uses the following string with this: "Failed to create a group: %08X".
 
[[Mario Kart Live: Home Circuit|mklive]] uses the following string with this: "Failed to create a group: %08X".
Line 659: Line 663:     
=== SetAdvertiseData ===
 
=== SetAdvertiseData ===
Takes a type-0x21 input buffer, no output.
+
Takes a type-0x21 input buffer. No output.
    
The buffer size must be <=0x80. The [[#GetRole|role]] must be <=1.
 
The buffer size must be <=0x80. The [[#GetRole|role]] must be <=1.
Line 666: Line 670:     
=== SendToOtherGroup ===
 
=== SendToOtherGroup ===
Takes an input [[#MacAddress_2|MacAddress]], a [[#GroupId]], a s16 frequency, a s16 channel, an u32 flags, a type-0x21 input buffer, no output.
+
Takes an input [[#MacAddress_2|MacAddress]], a [[#GroupId]], a s16 '''Frequency''', a s16 '''Channel''', an u32 '''MessageFlag''' and a type-0x21 input buffer. No output.
    
The buffer size must be <=0x400.
 
The buffer size must be <=0x400.
Line 677: Line 681:     
The [[#GetRole|role]] must be non-zero. The error from [[#GetNetworkInterfaceLastError]] will be returned if it's set.
 
The [[#GetRole|role]] must be non-zero. The error from [[#GetNetworkInterfaceLastError]] will be returned if it's set.
 +
 +
[11.0.0+] [[#GroupInfo]]+0x8A must be value 2, otherwise an error is returned.
    
This sends an Action frame to the specified [[#GroupId]], with the specified destination [[#MacAddress_2|MacAddress]] (can be a broadcast address).
 
This sends an Action frame to the specified [[#GroupId]], with the specified destination [[#MacAddress_2|MacAddress]] (can be a broadcast address).
Line 683: Line 689:     
=== RecvFromOtherGroup ===
 
=== RecvFromOtherGroup ===
Takes an input u32 flags, a type-0x22 output buffer, returns a [[#MacAddress_2|MacAddress]], an u16, a s16, an u32 out_size, a s32.
+
Takes an input u32 '''MessageFlag''' and a type-0x22 output buffer. Returns a [[#MacAddress_2|MacAddress]], an u16 '''Frequency''', a s16 '''Channel''', an u32 '''OutSize''' and a s32.
   −
The out_size is the original size used for copying to the output buffer, before it's clamped to the output-buffer size.
+
The OutSize is the original size used for copying to the output buffer, before it's clamped to the output-buffer size.
   −
Only bit0 is used from flags: clear = block until data is available, set = return error when data is not available.
+
Only bit0 is used from MessageFlag: clear = block until data is available, set = return error when data is not available.
    
When data is not available, the error from [[#GetNetworkInterfaceLastError]] will be returned if it's set.
 
When data is not available, the error from [[#GetNetworkInterfaceLastError]] will be returned if it's set.
Line 696: Line 702:     
=== AddAcceptableGroupId ===
 
=== AddAcceptableGroupId ===
Takes an input [[#GroupId]], no output.
+
Takes an input [[#GroupId]]. No output.
   −
=== RemoveAcceptableGroupId ===
+
=== ClearAcceptableGroupId ===
 
No input/output.
 
No input/output.
   −
== INetworkServiceMonitor ==
+
== ISfServiceMonitor ==
This is "nn::lp2p::detail::INetworkServiceMonitor".
+
This is "nn::lp2p::detail::ISfServiceMonitor".
    
This interface has no commands, until [9.1.0+] which added actual commands.
 
This interface has no commands, until [9.1.0+] which added actual commands.
Line 724: Line 730:  
| 288 || [[#GetGroupInfo]]
 
| 288 || [[#GetGroupInfo]]
 
|-
 
|-
| 296 || [[#Join]]
+
| 296 || [[#GetGroupInfo2]]
 
|-
 
|-
 
| 304 || [[#GetGroupOwner]]
 
| 304 || [[#GetGroupOwner]]
Line 730: Line 736:  
| 312 || [[#GetIpConfig]]
 
| 312 || [[#GetIpConfig]]
 
|-
 
|-
| 320 || [[#Leave]]
+
| 320 || [[#GetLinkLevel]]
 
|-
 
|-
 
| 328 || [[#AttachJoinEvent]]
 
| 328 || [[#AttachJoinEvent]]
Line 743: Line 749:     
=== AttachNetworkInterfaceStateChangeEvent ===
 
=== AttachNetworkInterfaceStateChangeEvent ===
No input, returns an output Event handle with EventClearMode=0.
+
No input. Returns an output Event handle with EventClearMode=0.
    
=== GetNetworkInterfaceLastError ===
 
=== GetNetworkInterfaceLastError ===
Line 749: Line 755:     
=== GetRole ===
 
=== GetRole ===
No input, returns an output u8.
+
No input. Returns an output u8.
    
=== GetAdvertiseData ===
 
=== GetAdvertiseData ===
Takes a type-0x22 output buffer, returns 2 output u16s.
+
Takes a type-0x22 output buffer. Returns two output u16s.
    
Validates that the [[#GetRole|role]] is value 2, then copies data from state into the output buffer. The first output u16 is the size used for the memcpy, the second u16 is the original size from state.
 
Validates that the [[#GetRole|role]] is value 2, then copies data from state into the output buffer. The first output u16 is the size used for the memcpy, the second u16 is the original size from state.
    
=== GetAdvertiseData2 ===
 
=== GetAdvertiseData2 ===
Takes a type-0x22 output buffer, returns 2 output u16s.
+
Takes a type-0x22 output buffer. Returns two output u16s.
    
This is identical to [[#GetAdvertiseData]] except this doesn't run the role validation.
 
This is identical to [[#GetAdvertiseData]] except this doesn't run the role validation.
Line 766: Line 772:  
Validates that the [[#GetRole|role]] is non-zero, then copies the struct from state into the output buffer.
 
Validates that the [[#GetRole|role]] is non-zero, then copies the struct from state into the output buffer.
   −
=== Join ===
+
=== GetGroupInfo2 ===
 
Takes a type-0x32 output buffer containing a [[#GroupInfo]] and a type-0x31 input buffer containing a [[#GroupInfo]].
 
Takes a type-0x32 output buffer containing a [[#GroupInfo]] and a type-0x31 input buffer containing a [[#GroupInfo]].
   Line 772: Line 778:     
=== GetGroupOwner ===
 
=== GetGroupOwner ===
No input, returns an output 0x80-bytes [[#NodeInfo_2|NodeInfo]].
+
No input. Returns an output [[#NodeInfo_2|NodeInfo]].
    
Validates that the [[#GetRole|role]] is non-zero, then copies the data from state to output.
 
Validates that the [[#GetRole|role]] is non-zero, then copies the data from state to output.
Line 783: Line 789:  
+0x20 is the <code>struct sockaddr</code> IP address, +0x40 is the <code>struct sockaddr</code> subnet-mask, +0x60 is the <code>struct sockaddr</code> gateway(?). The address for the last one is set to localhost.
 
+0x20 is the <code>struct sockaddr</code> IP address, +0x40 is the <code>struct sockaddr</code> subnet-mask, +0x60 is the <code>struct sockaddr</code> gateway(?). The address for the last one is set to localhost.
   −
=== Leave ===
+
=== GetLinkLevel ===
No input, returns an output u32.
+
No input. Returns an output u32.
    
=== AttachJoinEvent ===
 
=== AttachJoinEvent ===
No input, returns an output Event handle with EventClearMode=0.
+
No input. Returns an output Event handle with EventClearMode=0.
    
=== GetMembers ===
 
=== GetMembers ===
Takes a type-0x22 output buffer containing an array of [[#NodeInfo_2|NodeInfo]], returns an output s32 total_out.
+
Takes a type-0x22 output buffer containing an array of [[#NodeInfo_2|NodeInfo]]. Returns an output s32 '''TotalOut'''.
    
Validates that the [[#GetRole|role]] is value 1. Then any entries from state which are available are copied into the output array buffer, if there's space available. A maximum of 8 entries can be returned.
 
Validates that the [[#GetRole|role]] is value 1. Then any entries from state which are available are copied into the output array buffer, if there's space available. A maximum of 8 entries can be returned.
Line 797: Line 803:     
= lp2p:m =
 
= lp2p:m =
This is "nn::lp2p::detail::IMonitorServiceCreator".
+
This is "nn::lp2p::monitor::detail::ISfMonitorServiceCreator".
    
This was added with [9.1.0+].
 
This was added with [9.1.0+].
Line 809: Line 815:     
== CreateMonitorService ==
 
== CreateMonitorService ==
Takes a PID, a total of 0x10-bytes of input, and returns an [[#IMonitorService]].
+
Takes a PID-descriptor, a reserved input u64 and an input u64. Returns an [[#ISfMonitorService]].
   −
== IMonitorService ==
+
== ISfMonitorService ==
This is "nn::lp2p::detail::IMonitorService".
+
This is "nn::lp2p::monitor::detail::ISfMonitorService".
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 822: Line 828:  
| 288 || [[#GetGroupInfo]]
 
| 288 || [[#GetGroupInfo]]
 
|-
 
|-
| 320 || [[#Leave]]
+
| 320 || [[#GetLinkLevel]]
 
|}
 
|}
   Line 1,205: Line 1,211:  
! Description
 
! Description
 
|-
 
|-
| 0x0 || 0x10 || When zero, this is set to randomly-generated data. Used during key derivation.
+
| 0x0 || 0x10 || Wrapped master key. When zero, set to randomly-generated data. This is decrypted with a "static AES key" and used to derive the 4 encryption keys for the session.
 
|-
 
|-
| 0x10 || 0x8 || LocalCommunicationId. When zero, the value from control.nacp is loaded. This is later validated by [[#Join]]/[[#CreateGroup]] the same way as the [[#NetworkConfig]] field. Used during key derivation.
+
| 0x10 || 0x8 || LocalCommunicationId. When zero, the value from control.nacp is loaded. This is later validated by [[#Join]]/[[#CreateGroup]] the same way as the [[#NetworkConfig]] field. Used during key derivation to derive keys B and D.
 
|-
 
|-
 
| 0x18 || 0x6 || [[#GroupId]] ("GROUP ID  (BSSID)"). When zero, the default is used. The default should be used here: an error is thrown if the data here doesn't match the output from [[WLAN_services|wlan:lcl]] cmd2.
 
| 0x18 || 0x6 || [[#GroupId]] ("GROUP ID  (BSSID)"). When zero, the default is used. The default should be used here: an error is thrown if the data here doesn't match the output from [[WLAN_services|wlan:lcl]] cmd2.
 
|-
 
|-
| 0x1E || 0x21 || ServiceName ("GROUP NAME (SSID)"). NUL-terminated string. If the SSID is invalid, a new SSID is generated, however in this case the original SSID must contain a '-' character.
+
| 0x1E || 0x21 || ServiceName ("GROUP NAME (SSID)"). NUL-terminated string. See below.
 
|-
 
|-
 
| 0x3F || 0x1 || s8 Flags count. Must be <=0x3F.
 
| 0x3F || 0x1 || s8 Flags count. Must be <=0x3F.
 
|-
 
|-
| 0x40 || 0x40 || Array of s8 with the above count. Each entry value must be <=0x3F. Each entry is an array index used to load a set of flags from a global array with the specified index. global_flags are also masked with flags loaded from here.
+
| 0x40 || 0x40 || Array of s8 with the above count. Each entry value must be <=0x3F. Each entry is an array index used to load a set of flags from a global array with the specified index. global_flags are also masked with flags loaded from here. User-processes use entryval=1 as the default, with [11.0.0+] entryval=0 can be used for standard WPA2-PSK (see +0x8A).
 
|-
 
|-
| 0x80 || 0x1 || SupportedPlatform. Must match value 1. 0 is PlatformIdNX, 1 is PlatformIdFuji.
+
| 0x80 || 0x1 || SupportedPlatform. Must match value 1. 0 is PlatformIdNX, 1 is PlatformIdRcd.
 
|-
 
|-
 
| 0x81 || 0x1 || MemberCountMax. s8, Must be <=0x8. During group creation this is passed to [[WLAN_services|wlan:lcl]] cmd40, when this is value 0 a default of value 1 is passed. During group-creation when the below +0x88 field is not value 0x2, the passed [[BTM_services#SetWlanMode|WlanMode]] is <code>x81_field_val > 3</code>.
 
| 0x81 || 0x1 || MemberCountMax. s8, Must be <=0x8. During group creation this is passed to [[WLAN_services|wlan:lcl]] cmd40, when this is value 0 a default of value 1 is passed. During group-creation when the below +0x88 field is not value 0x2, the passed [[BTM_services#SetWlanMode|WlanMode]] is <code>x81_field_val > 3</code>.
Line 1,233: Line 1,239:  
| 0x89 || 0x1 || PerformanceRequirement.
 
| 0x89 || 0x1 || PerformanceRequirement.
 
|-
 
|-
| 0x8A || 0x1 || Security type, used during key derivation. 0 = use defaults, 1 = plaintext, 2 = encrypted.
+
| 0x8A || 0x1 || Security type, used during key derivation. 0 = use defaults, 1 = plaintext, 2 = encrypted. [11.0.0+] 3: Standard WPA2-PSK.
 
|-
 
|-
 
| 0x8B || 0x1 || StaticAesKeyIndex. s8, used as the array-index for selecting the KeySource used with [[SPL_services#GenerateAesKek|GenerateAesKek]] during key derivation. Should be 1-2, otherwise GenerateAesKek is skipped and zeros are used for the AccessKey instead.
 
| 0x8B || 0x1 || StaticAesKeyIndex. s8, used as the array-index for selecting the KeySource used with [[SPL_services#GenerateAesKek|GenerateAesKek]] during key derivation. Should be 1-2, otherwise GenerateAesKek is skipped and zeros are used for the AccessKey instead.
Line 1,243: Line 1,249:  
| 0x8F || 0x1 || If zero, a default value of 0x20 is used.
 
| 0x8F || 0x1 || If zero, a default value of 0x20 is used.
 
|-
 
|-
| 0x1C0 || 0x1 || PresharedKeyBinarySize. Must be 0x20 during key derivation.
+
| 0x1C0 || 0x1 || PresharedKeyBinarySize. Must be 0x20 for PresharedKeyBinary. [11.0.0+] With WPA2-PSK, this must be value 1.
 
|-
 
|-
| 0x1C1 || 0x20 || PresharedKey. Used during key derivation.
+
| 0x1C1 || 0x3F ([9.0.0-10.2.0] 0x20) || PresharedKey. Used to derive encryption keys A and C. [11.0.0+] With WPA2-PSK, this is the passphrase string (length must be at least 8).
 
|}
 
|}
   −
loaded_flags are first loaded from elsewhere, then masked with the above flags when available. loaded_flags are used when +0x8A is 0. global_flags are loaded from global data. These flags are only used with [[#CreateGroup]]/[[#Join]]. Flags:
+
In order for the ServiceName to be valid without a new one being generated, the following checks must pass:
 +
* It loops through the characters in the string, looking for the first '_' character:
 +
** The loop will exit once a '_' character is found.
 +
** The character must be '-', or alphanumeric (lowercase/uppercase), otherwise the function will immediately return failure.
 +
** The loop will also exit once string_pos is >19, in which case the function will also immediately return failure.
 +
* Then it checks the 11 characters which follow the above:
 +
** The character must be hex: '0'-'9', or 'A-F' / 'a-'f.
 +
* The following character must be a NUL-terminator.
 +
* The last hex character above, then the characters for the whole string prior to the last hex character are summed. return sum % 0x2B == 0. u32 is used for these calculations. (Return success when sum is a multiple of 0x2B, otherwise return failure)
 +
 
 +
If the above fails, then the following runs, otherwise it just returns 0:
 +
* It loops through the characters in the string.
 +
** The character must be '-', or alphanumeric (lowercase/uppercase), otherwise the function will immediately return failure.
 +
** The loop will exit once string_pos>20 is reached, or when a NUL-terminator is reached.
 +
* Once finished, success is returned if string_pos-1 is <20, otherwise failure is returned (which also immediately occurs if the first character is a NUL-terminator).
 +
 
 +
If the above fails, an error is returned, otherwise a new ServiceName is generated:
 +
* Up to 20 characters are copied from the original ServiceName to the output ServiceName, stopping once the limit is reached or when a NUL-terminator is reached.
 +
* '_' is appended to the string.
 +
* <code>nn::util::TSNPrintf({strptr following the above character}, {remaining size}, "%02X%02X%02X%02X%02X", [[#GroupId|GroupId_byte3]], [[#GroupId|GroupId_byte4]], [[#GroupId|GroupId_byte5]], ([[SPL_services#IsDevelopment|IsDevelopment]] ? 0x80 : 0) | 0x1, 0);</code>
 +
* Then the last character is set to the output from a calling a function:
 +
** All string characters which were already written are summed same way as above. Then: <code>return character_lookup_table[sum % 0x2B];</code> (If the length passed to this function is 0, this will instead just return character_lookup_table[0])
 +
*** character_lookup_table contains 0x2B entries: [V-A][k-a][5-0][Z-W].
 +
 
 +
 
 +
 
 +
loaded_flags are first loaded from elsewhere, then masked with the above flags when available. loaded_flags are used when +0x8A is 0. global_flags are loaded from global data. These flags are only used with [[#CreateGroup]]/[[#Join]]. Flags (note that the following was updated with [11.0.0+], and differs from below):
 
* Bit2 clear:
 
* Bit2 clear:
 
** global_flags must be non-zero, and loaded_flags bit1 must be set.
 
** global_flags must be non-zero, and loaded_flags bit1 must be set.
Line 1,501: Line 1,533:     
== lp2p ==
 
== lp2p ==
This is used for communicating with accessories over local wifi - in particular, [[Mario Kart Live: Home Circuit]] uses this.
+
This is used for communicating with accessories (external devices on [11.0.0+]) over local wifi. [[Mario Kart Live: Home Circuit]] uses this. [11.0.0+] [[Album_Applet|LibraryAppletPhotoViewer]] uses this.
    
A beacon is broadcasted.
 
A beacon is broadcasted.
Line 1,509: Line 1,541:  
Communication uses sockets with standard Data frames and the above Action frames. Switch consoles presumably only use the Action frames to communicate with each other?
 
Communication uses sockets with standard Data frames and the above Action frames. Switch consoles presumably only use the Action frames to communicate with each other?
   −
The key derived by ldn-sysmodule is used directly as the static CCMP key for all data-frames (CCMP / MIC is standard).
+
Key A derived by ldn-sysmodule is used directly as the static CCMP key for all data-frames (CCMP / MIC is standard). However, with [[#GroupInfo]]+0x8A value 3, standard WPA2-PSK is used instead.
 
  −
This uses infrastructure-mode (AccessPoint), and DHCP is used. The group-owner is the AccessPoint. Note that the probe response includes the same Nintendo tags included with the beacon. Once connected, the group-owner sends the same Epigram-vendor Action frame(s) described in [[#ldn]].
     −
It's unknown whether any custom authentication is used.
+
This uses infrastructure-mode (AccessPoint), and DHCP is used. The group-owner is the AccessPoint. Note that the probe response includes the same Nintendo tags included with the beacon. Once connected, the group-owner sends the same Epigram-vendor Action frame(s) described in [[#ldn]]. At this point socket communication can begin, including DHCP usage.
   −
The DHCP server thread is started by the "nn.lp2p.StateMachine" thread eventually during group [[#CreateGroup|creation]]. The DHCP Offer option values are the following, at least when connecting with encryption disabled from a Linux machine:
+
The DHCP server thread is started by the "nn.lp2p.StateMachine" thread eventually during group [[#CreateGroup|creation]]. The DHCP Offer option values are the following:
 
* "Subnet Mask: 255.255.255.0"
 
* "Subnet Mask: 255.255.255.0"
 
* "DHCP Server Identifier: {...}"
 
* "DHCP Server Identifier: {...}"
Line 1,527: Line 1,557:     
=== Beacon ===
 
=== Beacon ===
The SSID in the beacon is hidden (all-zero with the same length as the original SSID). The beacon contains two custom Nintendo tags with OUI <code>00:22:aa</code>. The beacon is identical to ldn, except for the following (besides SSID length difference and the lp2p-only Nintendo tags):  
+
The SSID in the beacon can optionally be [[#GroupInfo|hidden]] (all-zero with the same length as the original SSID). The beacon contains two vendor-specific Nintendo information elements with OUI <code>00:22:aa</code>; each IE has a 2-byte ID following the OUI. These Nintendo IEs are not used when standard WPA2-PSK is being used.
* "Tag: Traffic Indication Map (TIM)": "DTIM count" for lp2p is 1, with ldn it's 0.
+
 
 +
The beacon is identical to ldn, except for the following (besides SSID length difference and the lp2p-only Nintendo tags):  
 
* "Tag: HT Capabilities (802.11n D1.10)": "HT Short GI for 20MHz" is set to "Not supported", for ldn it's "Supported".
 
* "Tag: HT Capabilities (802.11n D1.10)": "HT Short GI for 20MHz" is set to "Not supported", for ldn it's "Supported".
 
* "Tag: Vendor Specific: Microsoft Corp.: WMM/WME: Parameter Element" "Ac Parameters ACI 0": "CW Min: 15" for lp2p, "CW Min: 63" for ldn.
 
* "Tag: Vendor Specific: Microsoft Corp.: WMM/WME: Parameter Element" "Ac Parameters ACI 0": "CW Min: 15" for lp2p, "CW Min: 63" for ldn.
   −
Note that during group creation the beacon may be missing the Nintendo tags in some cases, since group creation didn't finish yet.
+
Note that during group creation the beacon may be missing the Nintendo IEs in some cases, since group creation didn't finish yet.
 +
 
 +
==== Nintendo IE 0 ====
   −
The first Nintendo tag contains the following data:
+
The first Nintendo IE (ID 0x0600) contains the following fixed parameters:
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,542: Line 1,575:  
! Description
 
! Description
 
|-
 
|-
| 0x0 || 0x2 || Usually 06 00?
+
| 0x0 || 0x1 || Fixed 0x20; perhaps a version or other magic number.
 +
|-
 +
| 0x1 || 0x1 || [[#GroupInfo|SecurityType]]
 +
|-
 +
| 0x2 || 0x1 || [[#GroupInfo|StaticAesKeyIndex]]
 
|-
 
|-
| 0x2 || 0x2 || Usually 20 02?(Second byte depends on whether encryption is used?)
+
| 0x3 || 0x1 || Fixed zero; padding byte.
 
|-
 
|-
| 0x4 || 0x2 || Usually 01 00 or 02 00?(varies)
+
| 0x4 || 0x8 || Big-endian (i.e. byte-reversed) version of [[#GroupInfo|LocalCommunicationId]]. This is the only context where LocalCommunicationId is reversed.
 
|-
 
|-
| 0x6 || 0x8 || Big-endian version of [[#GroupInfo]]+0x10.
+
| 0xC || 0x10 || Wrapped master key. Same as [[#GroupInfo]]+0x0.
 
|-
 
|-
| 0xE || 0x10 || Same as [[#GroupInfo]]+0x0.
+
| 0x1C || 0x4 || If encryption is enabled, a randomly-generated nonce, else nothing. Appending 8 zero bytes to this yields the AES-GCM IV.
 
|-
 
|-
| 0x1E || || Start of encrypted (and crypto-related) data if enabled. 0x22-bytes when encrypted, 0xE-bytes when plaintext.
+
| 0x20 || 0x10 || If encryption is enabled, the AES-GCM MAC tag, else nothing. All bytes prior to this (fixed 0x20 through nonce) are the additional authenticated data. All bytes after this are encrypted with key B.
 
|}
 
|}
   −
The second Nintendo tag contains the following data (data starting at +0x2 is encrypted if enabled, there's also an additional 0x14-bytes when encrypted):
+
After this, TLV tagged parameters occur. Each TLV tag is formatted as:
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 1,563: Line 1,600:  
! Description
 
! Description
 
|-
 
|-
| 0x0 || 0x2 || Usually 06 01?
+
| 0x0 || 0x1 || Tag type
 
|-
 
|-
| 0x2 || 0x1 || Plaintext: usually 21?
+
| 0x1 || 0x1 || Length
 
|-
 
|-
| 0x3 || 0x1 || Plaintext: AdvertiseData size
+
| 0x2 || {above size} || Data for the tag
 +
|}
 +
 
 +
Known TLV tags:
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Type
 +
! Size
 +
! Description
 +
|-
 +
| 0x1 || 0x2 || Additional network parameters: 0xAB 0xCD. A=[[#GroupInfo]]+0x82, B=[[#GroupInfo|MemberCountMax]], C=[[#GroupInfo|NetworkMode]], D=[[#GroupInfo|PerformanceRequirement]].
 +
|-
 +
| 0x2 || 0x8 || Flags: Bitwise-or of (1<<f) for each entry in [[#GroupInfo]]+0x40
 +
|}
 +
 
 +
==== Nintendo IE 1 ====
 +
 
 +
The second Nintendo IE (ID 0x0601) contains only TLVs. If encryption is enabled, a 0x4-byte nonce and 0x10-byte AES-GCM tag are written first, as above, and the TLVs are encrypted. Key C is used.
 +
 
 +
Known TLV tags:
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
! Type
 +
! Size
 +
! Description
 
|-
 
|-
| 0x4 || {above size} || Plaintext: AdvertiseData
+
| 0x21 || Varies || AdvertiseData
 
|}
 
|}
  

Navigation menu