Network Protocol/Server/mariokartwii.master.gs.nintendowifi.net
QUERY (0x00)
This is not used by MKWii. This packet is sent by the server and answered by the client.
FE FD 00 43 4F 52 59 FF FF 00
FE FD Server-Message 00 is the message type 43 4F 52 59 is the Client-ID FF indicates if server info and rules should get returned (0xFF = yes, 0x00 = no) FF indicates if player info should get returned (same as above) 00 indicates if team info should get returned (same as above)
CHALLENGE (0x01)
The packet from the Wii for Authentication looks like this:
01 82 2B 3E 31 55 71 35 72 45 70 68 79 75 30 48 38 4F 30 7A 6F 43 2F 55 2F 51 38 6B 6B 52 66 51 41 00
01 is the message type (CHALLENGE) 82 2B 3E 31 is the Client-ID 55 71 35 72 45 70 68 \ 79 75 30 48 38 4F 30 \ 7A 6F 43 2F 55 2F 51 \ 38 6B 6B 52 66 51 41 challenge 00 end
The Server-Answer for 0x01 (so starting with 0xFEFD01) has the following format:
FE FD 01 82 2B 3E 31 30 4C 7B 6F 7E 5A 30 30 30 41 30 30 30 30 30 36 39 46 31 36 00
FE FD Server message 01 is the message type (CHALLENGE_RESPONSE) 82 2B 3E 31 is the Client-ID 30 4C 7B 6F 7E 5A 30 30 is a printable ASCII (but not BASE64) string with 6 random bytes and an appended 0x3030. Challenge-string. 30 41 30 30 30 30 30 36 is the client-external-IP4 as hexdump: "30 41" ⇒ "0a" ⇒ 10 for 10.0.0.6. 39 46 31 36 is the external client port as hexdump: "39 46 31 36" ⇒ "9f16" ⇒ 40726 00 end
ECHO (0x02)
This is not needed for MKWii but it might be important for other games.
The Server sends a packet starting with "0xFEFD02" to check if we are behind NAT. If the Wii sends no answer, the Server knows we are behind NAT and need NATNEG. The Wii would answer with 0x05 (ECHO_RESPONSE) if it received an answer, but this never happens because it's always behind NAT (hard-coded in game).
HEARTBEAT (0x03)
The HEARTBEAT-Record is sent by the client during a race or a connection to WFC.
It starts with one byte which is always 0x03 indicating that a HEARTBEAT-message follows. Bytes 0x2 to 0x5 are a 4-Byte-Client-ID
After that, there follows this data:
localip0.<local-IP>. localip1.190.190.190.190. localport.<local port (or 0)>. natneg.<natneg>. gamename.mariokartwii. publicip.<latest reachable host on traceroute to client>. publicport.<public port (or 0)>. numplayers.<player count minus 1>. maxplayers.<max player count>. unknown.<dwc-profile-id>. unknown.<dwc_mtype>. unknown.<dwc_mver>. unknown.<dwc_eval>. unknown.<dwc_groupid>. unknown.<dwc_hoststate>. unknown.<dwc_suspend>
<max player count> is the max number of guests, so it's either 0 or 11. <natneg> indicates if NAT negotiation is needed, this is always "1" in MKWii. If <publicip> is 0 or not set, the server sends a 0xFEFD01-packet containing the IP.
Dolphin has a little bug in this packet, when using Dolphin, localip0 is always 10.0.1.30. But this is only a problem if the client is behind the same NAT than the server (and does not need natneg).
ADDERROR (0x04)
A packet starting with 0xFEFD04 is sent by the server to tell the client he is behind NAT and the echo packet didn't arrive.
ECHO_RESPONSE (0x05)
This does never happen on a Wii, since "firewall=1" is hardcoded in the games. This normally gets sent by the client to tell the server that the ECHO-message arrived.
CLIENT_MESSAGE (0x06)
There are two (or more?) different variants of message type 0x06 - the first one is very short and contains a player ID and a natneg packet. The second one contains a player ID and some other data, but no natneg. Both types are sent by the server. Sometimes a client sends the second part of type 2 (starting at 0xBB49CC4D) to the ms19-server.
Type 1
FE FD 06 EC 95 5A 32 05 8E 2B D9 FD FC 1E 66 6A B2 6A 72 00 71
FE FD Server-Message 06 message-type EC 95 5A 32 is the client-ID 05 8E 2B D9 is any unknown payload (seems to be upcounting) FD FC start of natneg-packet 1E 66 6A B2 is the natneg-constant 6A 72 00 71 is the client-ID of the other client
Type 2
Type 2 also has some sub types which differ in length and content. This type seems to be very similar with the STATUS-Record in the P2P data.
Sub-type 0x01
FE FD 06 C4 80 B5 5C 03 6C 79 5C BB 49 CC 4D 5A 00 00 00 01 24 38 EE 55 16 82 4C A5 95 85 1C 00 00 00 00 55 16 82 4C 38 EE 00 00 AC 16 35 02 38 EE 00 00 01 00 00 00 00 00 00 00 01 00 00 00 AF 97 4F DF
FE FD Server-Message 06 message-type C4 80 B5 5C is the client-ID 03 6C 79 5C is any unknown payload BB 49 CC 4D 5A 00 00 00 unknown_1 01 sub type ID 24 data length (complete length of packet = 0x14 + 0x24 = 56 bytes) 38 EE public port 55 16 82 4C public IP address A5 95 last two bytes of FC 85 1C unknown_2 00 00 00 00 unknown_3, maybe always 0x00000000 55 16 82 4C traceable IP address 38 EE public port 00 00 unknown_4 AC 16 35 02 local IP address 38 EE public port 00 00 01 00 00 00 00 00 00 \ 00 01 00 00 00 unknown_5 AF 97 4F DF unknown_6
Sub-type 0x02
FE FD 06 EC 95 5A 32 05 8E 2B D9 BB 49 CC 4D 5A 00 00 00 02 34 1B EC 55 16 82 4C F0 95 85 1C 0B 00 00 00 00 00 00 00 F0 95 85 1C 55 16 82 4C 1B EC 00 00 C0 A8 B2 33 1B EC 00 00 01 00 00 00 01 00 00 00 98 E1 A2 22 01 00 00 00 01 00 00 00 AF 97 4F DF
FE FD Server-Message 06 message-type EC 95 5A 32 is the client-ID 05 8E 2B D9 is any unknown payload BB 49 CC 4D 5A 00 00 00 unknown_1 02 sub type ID 34 unknown_7 1B EC public port (little endian) 55 16 82 4C public IP address F0 95 85 1C unknown_2 0B 00 00 00 unknown_3 00 00 00 00 unknown_5, maybe always 0x00000000 F0 95 85 1C unknown_2 55 16 82 4C traceable IP (see description below) 1B EC public port (little endian) 00 00 unknown_4 C0 A8 B2 33 local IP address 1B EC local port 00 00 01 00 00 00 01 00 00 \ 00 98 E1 A2 22 01 00 00 00 \ 01 00 00 00 unknown_5 AF 97 4F DF unknown_6
The value "traceable IP" means the last reachable host on the route to the client. Do a traceroute on publicip and put the farthest reachable host here. This is the behaviour of the official server, but probably it'd be enough to simply put the public IP here.
Sub-type 0x04
FE FD 06 C4 80 B5 5C 03 6C 7B 9E BB 49 CC 4D 5A 00 00 00 04 00 38 EE 55 16 82 4C A5 95 85 1C
FE FD Server-Message 06 message-type C4 80 B5 5C is the client-ID 03 6C 7B 9E is any unknown payload BB 49 CC 4D 5A 00 00 00 unknown_1 04 sub type ID 00 unknown_2 38 EE public port 55 16 82 4C public IP address A5 95 85 1C unknown_3
Sub-type 0x06
FE FD 06 B8 A1 E0 D5 03 6C 7E 48 BB 49 CC 4D 5A 00 00 00 06 08 38 EE 55 16 82 4C A5 95 85 1C AC 16 35 02 38 EE 00 00
FE FD Server-Message 06 message-type B8 A1 E0 D5 is the client-ID 03 6C 7E 48 is any unknown payload BB 49 CC 4D 5A 00 00 00 unknown_1 06 sub type ID 08 unknown_2 38 EE public port 55 16 82 4C public IP address A5 95 85 1C unknown_3 AC 16 35 02 probably any local IP address 38 EE public port 00 00 unknown_5
CLIENT_MESSAGE_ACK (0x07)
This is the answer of the client to 0x06.
07 EC 95 5A 32 05 8E 2B D9
07 message-typ EC 95 5A 32 is the client-ID 05 8E 2B D9 any unknown payload (same as in 0x06)
KEEPALIVE (0x08)
This is sent by the client.
08 82 2B 3E 31
08 is the message type (KEEPALIVE) 82 2B 3E 31 is the client-ID
AVAILABLE (0x09)
This packet gets handled by the available-server.
CLIENT_REGISTERED (0x0A)
The server returns that the client is logged in now. This gets sent after CHALLENGE.
FE FD 0A 3D B0 A8 D6 00 00 00 00 00 00 00 00 00 00 00
FE FD Server-Message 0A is the message type (RESPONSE_CORRECT) 3D B0 A8 D6 is the client-ID 00 00 00 00 00 00 00 00 00 00 00 is the empty data.