NWM Services
These NWM services are used for local-WLAN communications, NWM module handles regular wifi APs as well. These services are used for creating/connecting to networks, and for sending/receiving data over the network etc. NWM module uses the wifi SDIO hardware via the IO registers for this.
NWM local-WLAN service "nwm::UDS"
Command Header | Available since system version | Description |
---|---|---|
0x00010442 | Initialize Deprecated. Appears to be handled about the same way as NWMUDS:InitializeWithVersion, except this uses version=0x100 internally instead of loading it from the command request. | |
0x00020000 | Scrap Not used by sub-wars. This sets a state value to 0x2 then signals an event. This is probably some sort of shutdown command since this state write will result in all UDS commands returning an error if used afterwards. | |
0x00030000 | Shutdown | |
0x00040402 | CreateNetwork Deprecated. Only used by very old titles. | |
0x00050040 | EjectClient | |
0x00060000 | EjectSpectator | |
0x00070080 | UpdateNetworkAttribute | |
0x00080000 | DestroyNetwork | |
0x00090442 | ConnectNetwork Deprecated. Only used by very old titles. | |
0x000A0000 | DisconnectNetwork | |
0x000B0000 | GetConnectionStatus | |
0x000C0000 | This writes two output u8 values to cmdreply[2] +0/+1. Not used by sub-wars. | |
0x000D0040 | GetNodeInformation | |
0x000E0006 | Unknown. Not used by sub-wars. | |
0x000F0404 | RecvBeaconBroadcastData | |
0x00100042 | SetApplicationData | |
0x00110040 | GetApplicationData | |
0x00120100 | Bind | |
0x00130040 | Unbind | |
0x001400C0 | PullPacket | |
0x00150080 | SetMaxSendDelay(u32 unk0, u32 unk1) Not used by sub-wars. | |
0x00160040 | (u8 inputval) Unknown. Not used by sub-wars. | |
0x00170182 | SendTo | |
0x00180040 | (u16 inputval) Unknown. Not used by sub-wars. | |
0x00190040 | (u32 inputval) Unknown. Not used by sub-wars. | |
0x001A0000 | GetChannel | |
0x001B0302 | InitializeWithVersion | |
0x001C0040 | (u8 inputval) Unknown. Not used by sub-wars. | |
0x001D0044 | Unknown, >2.0.0-2 | BeginHostingNetwork This is a replacement for the original network-creation command. |
0x001E0084 | Unknown, >2.0.0-2 | ConnectToNetwork This is a replacement for the original network-connection command. |
0x001F0006 | Unknown, >2.0.0-2 | DecryptBeaconData |
0x00200040 | Unknown, >2.0.0-2 | Flush (u8 data_frame_index) Unknown. Not used by sub-wars. |
0x00210080 | Unknown, >2.0.0-2 | SetProbeResponseParam |
0x00220402 | Unknown, >2.0.0-2 | ScanOnConnection |
0x00230000 | Unknown, >2.0.0-2 | This writes an output u16 value to cmdreply[2]. Unknown. Not used by sub-wars. |
PullPacket is used for receiving data over the network and SendTo is for sending data over the network.
NWM infrastructure service "nwm::INF"
Command Header | Description |
---|---|
0x000603C4 | RecvBeaconBroadcastData |
0x00070742 | ConnectToEncryptedAP |
0x0008.... | ConnectToAP |
NWM socket service "nwm::SOC"
NWM service "nwm::SAP"
NWM local-WLAN StreetPass service "nwm::CEC"
Command Header | Description |
---|---|
0x00060002 | Unknown, called by CECD module, cmdbuf[2] takes an event handle |
0x000D0082 | SendProbeRequest |
NWM service "nwm::EXT"
Command Header | Available since system version | Description |
---|---|---|
0x0001.... | <=2.0.0-2 | ? |
0x0002.... | <=2.0.0-2 | ? |
0x0003.... | <=2.0.0-2 | ? |
0x0004.... | <=2.0.0-2 | ? |
0x0005.... | <=2.0.0-2 | ? |
0x0006.... | <=2.0.0-2 | ? |
0x00070000 | <=2.0.0-2 | This copies 0x1C-bytes from NWM-module state to the data starting at cmdreply[2]. |
0x00080040 | <=2.0.0-2 | ControlWirelessEnabled |
0x0009.... | <=2.0.0-2 | ? |
NWM service "nwm::TST"
Local-WLAN
UDS is used for 3DS<>3DS local-WLAN communications, and for 3DS<>Wii U communications. The latter is mainly only used for multi-player in games.
All UDS local-WLAN communications have the CCMP key for data encryption generated via NWM module. The CCMP key passed to nwm::CEC commands(stored in a 0x44-byte input structure) for StreetPass is generated by the CECD module. The input data used with EncryptDecryptAes with keytype1 is a MD5 hash over the input passphrase. This input passphrase is fixed for Download Play, it's unique per local-WLAN application. The CTR is a MD5 hash over the below 0x10-byte structure. The output from encrypting that data with AES-CTR is the final CCMP key. This passphrase is a raw input buffer: while the passphrase specified by user-processes is normally a string with the NUL-terminator included, it can be anything(like the WirelessRebootPassphrase for example).
The maximum number of nodes(including the host) which can be on an UDS network is 16.
NodeID
Only one spectator can be connected to the network at a time. DLP-client connects to the network as a spectator during DLP scanning to get icon data.
NetworkNodeID
This is the network u16 ID for each device on the UDS network. NodeID 0xFFFF is a broadcast alias. 0x1 is for the host, the 0x2 for the first client, 0x3 for the second client, and so on.
The spectator doesn't have a NetworkNodeID, since it can't send any data.
BindNodeID
This u32 is an ID only used on the local device. How many devices are on the network or which device this system is does not affect this ID.
The spectator uses BindNodeID 0x1. DLP uses BindNodeID 0x3 when connecting as an actual client. Hence, it seems BindNodeID bit0 is spectator-related. All normal nodes(host/client) start with BindNodeID 0x2. When connecting to a network again(and probably with network creation) without reinitializing NWMUDS, official user processes increase the used BindNodeID by 0x2.
BindNodeID value 0x0 is invalid. The maximum number of BindNodeIDs which can be open at the same time is 16.
Application data transfer
The protocol used for sending/receiving data over the network with UDS by official applications is PRUDP(in some cases at least). In some cases at least this is with PRUDPS(additional encryption layer). This includes UDS-specific data in each frame, such as Mii data. Mario Kart 7 uses PRUDPS here.
Data frames
Data is transferred over the network using NWMUDS:PullPacket/NWMUDS:SendTo. That data is transferred using 802.11 data frames using CCMP encryption. The encrypted data contained in the frame starts with a 0xE-byte NWM header, followed by the actual application data from the previously mentioned commands. When NWMUDS:SendTo was used with dst_NodeID = broadcast, the data frame is sent to the 802.11 broadcast MAC address. Otherwise with a specific NodeID, the data frame is sent to the actual MAC address for that device.
Structure used for generating the CTR for CCMP key generation
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Local-WLAN communication ID, normally this is: (user_process uniqueID << 8) | val. Where val is 0x10 on retail(configmem UNITINFO bit0 set), 0x90 for devunit. For Download Play, this is always 0x2810 on retail(0x2890 on devunit). |
0x4 | 0x4 | u32 networkID, randomly-generated when creating the network. The network SSID used when a client connects to the network is sprintf(out, "%08X", networkID). |
0x8 | 0x6 | Host MAC address. |
0xE | 0x2 | ID, for Download Play this is 0x55. |
This data is stored as little-endian.
CTR used for beacon tags crypto
Offset | Size | Description |
---|---|---|
0x0 | 0x6 | Host MAC address |
0x6 | 0x4 | wlancommID |
0xA | 0x1 | This ID is also stored at offset 0xE in the CTR-generation structure. |
0xB | 0x1 | Padding, value zero. |
0xC | 0x4 | This is the u32 from offset 0x18 in the network-struct. |
This data is stored as little-endian. All data here is all-zero except for the MAC address, when the u8 at offset 0x8 in the network-struct is 0.
Network structure
Offset | Size | Description |
---|---|---|
0x0 | 0x6 | This is the MAC address of the host. This is all-zero on the host, like with NWMUDS:BeginHostingNetwork. |
0x8 | 0x1 | This is non-zero when at least one entry is stored in the array under the encrypted beacon data. |
0xC | 0x3 | This is the OUI value for use with the beacon tags. Normally this is 001F32. |
0xF | 0x1 | OUI type (21/0x15) |
0x10 | 0x4 | wlancommID |
0x14 | 0x1 | This ID is also stored at offset 0xE in the CTR-generation structure. |
0x16 | 0x2 | This u16 bitmask can be written via NWMUDS:UpdateNetworkAttribute. When bitmask 0x2 is set, new Clients are not allowed to connect. Bitmask 0x4 is probably the same as 0x2 except for Spectators. |
0x1C | 0x1 | ? |
0x1D | 0x1 | This is the total number of entries stored under the array in the encrypted beacon data. |
0x1E | 0x1 | ? |
0x1F | 0x1 | ? |
0x3F | 0x1 | Size of appdata. Normally zero. |
0x40 | 0xC8 | Appdata(Application data), if any. Size of the appdata is specified via the u8 at offset 0x3F. This data is not used when the size-field is zero. |
This 0x108-byte structure is used for NWMUDS:BeginHostingNetwork, NWMUDS:ConnectToNetwork, etc. This data is stored as big-endian.
UDS Beacons
The UDS host broadcasts a beacon containing at least two Nintendo-vendor tags(tag number 0xDD, see above for the OUI), normally the data stored in these tags are static. The second tag contains the big-endian u32 networkID, used by the clients when connecting to the host and for the above CCMP key generation. The Nintendo-vendor tag(s) following the first two are unique to the process using UDS, these tags are used for broadcasting metadata regarding the host.
A tool for these beacons is available here: [1]
UDS Beacon Tags
The following is the structure of each tag, starting at the OUI. The order of the tags is the same as listed below. All data stored under these tags are stored as big-endian.
OUI Type 20
Offset | Size | Description |
---|---|---|
0x0 | 0x3 | OUI, see above. |
0x3 | 0x1 | OUI type (20/0x14) |
0x4 | 0x3 | Sample data: 0a 00 00 |
Normally the size of this tag(from the tag size field) is 0x07.
OUI Type 21
Offset | Size | Description |
---|---|---|
0x0 | 0x1F | This is the network structure starting at offset 0xC, with the first 0x1F-bytes from there. |
0x1F | 0x14 | SHA1 hash. When doing the hashing, this hash is cleared to zero. The hash data starts at offset 0x0(OUI), and the size is 0x34 + <value of the u8 at offset 0x33>. |
0x33 | 0x1 | Size of appdata. Normally zero. When non-zero this appdata is located at offset 0x34. |
Normally the size of this tag(from the tag size field) is 0x34.
OUI Type 24
Offset | Size | Description |
---|---|---|
0x0 | 0x3 | OUI, see above. |
0x3 | 0x1 | OUI type (24/0x18) |
0x4 | See below | Encrypted data |
This is the tag0 used with NWMUDS:DecryptBeaconData. The size of data stored under this tag has a maximum size of 0xFA-bytes, however normally the size is smaller than that. Additional encrypted data, if any, is stored under the below tag1.
OUI Type 25
Offset | Size | Description |
---|---|---|
0x0 | 0x3 | OUI, see above. |
0x3 | 0x1 | OUI type (25/0x19) |
0x4 | See above | Encrypted data |
When this exists in the beacon, this is the tag1 used with NWMUDS:DecryptBeaconData. The data stored here is the 0xFA-bytes following the previous encrypted data in tag0, for more space for storing the encrypted data.
Encrypted beacon data
The following structure is for the plaintext version of the encrypted data.
This data is encrypted with AES-CTR, by NWM module in software. The AES key is stored in NWM module itself. See above for the CTR. The size of this encrypted data is 0x12 + (0x1E*val), where val is the u8 from networkstruct offset 0x1D(zero when the u8 at networkstruct offset 0x8 is value zero).
Structure
Offset | Size | Description |
---|---|---|
0x0 | 0x10 | MD5 over the rest of the data following this(plaintext). |
0x10 | 0x2 | ? |
0x12 | 0x1E * <total array entries> | This is an array of entries for each of the devices on this network, the first entry is for the host and the rest is for the client(s). |
Array entry
Offset | Size | Description |
---|---|---|
0x0 | 0x18 | This is the first 0x18-bytes of the structure from here. |
0x18 | 0x4 | ? |
0x1C | 0x2 | ? |
Errors
Error code | Description |
---|---|
0xC8A06C0D | The operation being performed is already done (e.g., if you run NWMEXT_ControlWirelessEnabled to turn wifi on when it's on already, you can't turn it on again). |