Network Protocol/Server/mariokartwii.natneg.gs.nintendowifi.net

From Custom Mario Kart
Jump to navigation Jump to search

NATNEG is an abbreviation for NAT (Network Address Translation) and NEGotiation. The goal is to enable the communication between 2 clients with both using a router with NAT.



Server

In general, Gamespy uses up to 5 domains for each game following the name scheme:

<GAMENAME>.natneg1.gamespy.com
<GAMENAME>.natneg2.gamespy.com
<GAMENAME>.natneg3.gamespy.com
<GAMENAME>.natneg4.gamespy.com
<GAMENAME>.natneg5.gamespy.com

For Mario Kart Wii they use three domains:

mariokartwii.natneg1.gs.nintendowifi.net
mariokartwii.natneg2.gs.nintendowifi.net
mariokartwii.natneg3.gs.nintendowifi.net

All domains point to different IP addresses and all servers listen at port 27901 for UDP packets.

In MKWii, only natneg1 does the real "NAT Negotiation". The other two servers are used for a STUN service (determining the NAT type (full cone, restricted cone, restricted port) as used in STUN services) which is done by the system menu.

Connection Protocol

The NATNEG communication to enable a peer to peer communication is is done in the following steps:

  1. Both clients (called guest and host to distinguish them) exchange an unique natneg-id. In all observed Wii games this communication is done using Server MS and Server MASTER.
  2. Both clients sends independent of each other a sequence of 4 INIT packets to the NATNEG servers. The sequence number goes from 0 to 3. The guest sets the host_flag to 0 and the host to 1. The natneg-id must be the same for all packets.
    • Packet 0 (sequence number 0) is send from the public address to server NATNEG1. This public address is later used for the peer to peer communication.
    • Packet 1 (sequence number 1) is send from the communication address (usually an other port than the public address) to server NATNEG1.
    • Packet 2 (sequence number 2) is send from the communication address to server NATNEG2 (only used for STUN).
    • Packet 3 (sequence number 3) is send from the communication address to server NATNEG3 (only used for STUN).
  3. Each INIT packet is answered by an INIT_ACK packet as acknowledge to the original sender.
  4. When server NATNEG1 has received all 4 INIT packets with sequence numbers 0 and 1 (same natneg-id), it waits 10ms and sends 2 CONNECT packets:
    • One packet is send to the communication address of the guest. The packet contains the public address of the host as data.
    • The other packet is send to the communication address of the host. The packet contains the public address of the quest as data.
  5. Both clients send back a CONNECT_ACK packet to NATNEG1 as acknowledge.
  6. Both clients start peer to peer communication using the public addresses.
  7. On success, both clients send a REPORT packet to NATNEG1 as acknowledge with STATUS=1. On failure, the STATUS data field is set to 0. This packets arrives usually 7s after CONNECT. The server replies with REPORT_ACK.

Common Record Header

There are several NATNEG record types and all start with the same header. All data is stored in network byte order (big endian):

NATNEG General Header
Offset Type Description
0x00 u8[6] The NATNEG magic, always 0xfdfc1e666ab2.
0x06 u8 The protocol version. In MKWii always 0x03; in other games either 0x03 or 0x04.
0x07 u8 The record type, any value between 0x00 and 0x10.
0x08 * Record specific data

NATNEG Record Types

The byte at offset 0x07 of each record defines the NATNEG record type. natneg2 and natneg3 seem to be any fall back, they only send a single INIT and receive a single INIT_ACK.

The NATNEG records
Type Name Description
0x00 INIT Send by the client to initialize the connection.
0x01 INIT_ACK Reply by the server for record INIT (0x00).
0x02 ERT_TEST Used in connection test (wiinat.natnegX.gs.nintendowifi.net).
0x03 ERT_ACK Not used by MKWii.
0x04 STATUSUPDATE Not used by MKWii.
0x05 CONNECT (server or P2P) Reply by the server for record INIT (0x00), if an other client send an INIT request with the same USER-ID.
0x06 CONNECT_ACK Acknowledge of the client on CONNECT (0x05).
0x07 CONNECT_PING Only used in P2P, not in communication with the Server.
0x08 BACKUP_TEST Not used by MKWii.
0x09 BACKUP_ACK Not used by MKWii.
0x0A ADDRESS_CHECK Used in connection test (wiinat.natnegX.gs.nintendowifi.net).
0x0B ADDRESS_REPLY Used in connection test (wiinat.natnegX.gs.nintendowifi.net).
0x0C NATIFY_REQUEST Used in connection test (wiinat.natnegX.gs.nintendowifi.net).
0x0D REPORT
0x0E REPORT_ACK
0x0F PREINIT As the name says, in some games (not in MKWii) this is sent before INIT.
0x10 PREINIT_ACK

NATNEG Records

INIT (0x00)

This packet is sent from Wii to Nintendo.

fd fc 1e 66 6a b2 03 00 3d f1 00 71 00 00 01 0a 00 01 e2 00 00 6d 61 72 69 6f 6b 61 72 74 77 69 69 00
fd fc		Natneg
1e 66 6a b2	Natneg
03		NAT-Negotiation server version (for MKWii its 0x03)
00		natneg step 0x00
3d f1 00 71	client-ID for tracking the reply. Last two bytes (00 71) are last two bytes of FC of new client. 
00		"porttype" according to GS SDK. NN_PT_GP = 0 (game p2p port), NN_PT_NN1 = 1, NN_PT_NN2 = 2, NN_PT_NN3 = 3 (mappings)
00		hoststate (0x00 for guest, 0x01 for host)
01		use_game_port. Always 0x01 for MKWii. If this flag happens to be 0 for any game, this means that the game only opens one socket for both the p2p communication and the NN communication (the NN_PT_GP packet is not sent)
0a 00 01 e2	Private (internal) Wii IP adress (here it is 10.0.1.226)
00 00		This was thought for the local port, but in MKWii it's always 0x0000. 
6d 61 72 69 \
6f 6b 61 72 \
74 77 69 69	The game name. For MKWii its "mariokartwii"
00		End.

INIT_ACK (0x01)

This is sent from the server to the Wii.

fd fc 1e 66 6a b2 03 01 3d f1 00 71 00 00 ff ff 6d 16 b5 7d ea
fd fc		Natneg
1e 66 6a b2	Natneg 
03		NAT-Negotiation server version (for MKWii its 0x03)
01		natneg step 0x01
3d f1 00 71	client-ID for tracking the reply. Last two bytes (00 71) are last two bytes of FC of new client. 
00		"porttype" according to GS SDK. NN_PT_GP = 0 (game p2p port), NN_PT_NN1 = 1, NN_PT_NN2 = 2, NN_PT_NN3 = 3 (mappings)
00		hoststate (0x00 for guest, 0x01 for host)
ff ff		unknown_5. Always 0xffff
6d 16 b5 7d ea	unknown_6. Any useless constant (also for other games). 

ERT_TEST (0x02)

This is only used during connection test (Wii settings). This is sent by the server.

fd fc 1e 66 6a b2 03 02 00 00 03 09 02 00 00 00 00 00 00 00 00
fd fc		Natneg
1e 66 6a b2	Natneg
03		NAT-Negotiation server version (for MKWii its 0x03)
02		natneg step 0x02
00 00 03 09	unknown_1
02 		"porttype" according to GS SDK. NN_PT_GP = 0 (game p2p port), NN_PT_NN1 = 1, NN_PT_NN2 = 2, NN_PT_NN3 = 3 (mappings)
00 		reply flag (unknown)
00 00 00 00 /
00 00 00	unknown_2

ERT_ACK (0x03)

This is basically an answer for ERT_TEST. The client only changes the step to 0x03.

fd fc 1e 66 6a b2 03 02 00 00 03 09 02 00 00 00 00 00 00 00 00
fd fc		Natneg
1e 66 6a b2	Natneg
03		NAT-Negotiation server version (for MKWii its 0x03)
03		natneg step 0x03
00 00 03 09	unknown_1
02 		"porttype" according to GS SDK. NN_PT_GP = 0 (game p2p port), NN_PT_NN1 = 1, NN_PT_NN2 = 2, NN_PT_NN3 = 3 (mappings)
00 		reply flag (unknown)
00 00 00 00 /
00 00 00	unknown_2

CONNECT (0x05)

This is also sent from the server to the Wii.

fd fc 1e 66 6a b2 03 05 3d f1 00 71 18 ab ed 7a da 00 42 00
fd fc		Natneg
1e 66 6a b2	Natneg 
03		NAT-Negotiation server version (for MKWii its 0x03)
05		natneg step 0x05
3d f1 00 71	client-ID for tracking the reply. Last two bytes (00 71) are last two bytes of FC of new client. 
18 ab ed 7a     client's public IP
da 00		client's public port
42		got_data (Version 3: Always 0x42, Version 4: 1 if we have received a ping from remote, 0 otherwise)
00		Version 3: error (0x00: no error, 0x01: other client did not answer (p2p ping failed), 0x02: INIT timeout (other client didn't do INIT)), Version 4: 1 if we know remote has received a ping from us

CONNECT_ACK (0x06)

This is sent from Wii to server.

fd fc 1e 66 6a b2 03 06 3d f1 00 71 90 00 cd a0 80 00 00 00 90
fd fc		Natneg
1e 66 6a b2	Natneg
03		NAT-Negotiation server version (for MKWii its 0x03)
06		natneg step 0x06
3d f1 00 71	client-ID for tracking the reply. Last two bytes (00 71) are last two bytes of FC of new client. 
90 		unknown_19 (0x00, 0x80 or 0x90)
00 		reply flag / client index
cd a0 		unknown_14
80 		unknown_16
00 00 00 90	unknown_17

BACKUP_ACK (0x09)

The BACKUP_ACK is sent by the server as a response to BACKUP_TEST. The server only needs to send back the received packet with the natneg record type byte set to 0x09. The exact format of those records is unknown as MKWii does not use them.

ADDRESS_CHECK (0x0a)

This is only used during connection test (Wii settings). This is sent to wiinat.natnegX.gs.nintendowifi.net (X is a number between 1 and 3).

fd fc 1e 66 6a b2 03 0a 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
fd fc		Natneg
1e 66 6a b2	Natneg
03		NAT-Negotiation server version (for MKWii its 0x03)
0a 		natneg step 0x0a
00 00 00 01     ID, 0 to 4
01 		"porttype" according to GS SDK. NN_PT_NN1 = 1, NN_PT_NN2 = 2, NN_PT_NN3 = 3 (mappings)
60 * 0x00	unknown_5

ADDRESS_REPLY (0x0b)

This is only used during connection test (Wii settings). This is received from wiinat.natnegX.gs.nintendowifi.net (X is a number between 1 and 3).

fd fc 1e 66 6a b2 03 0b 00 00 00 03 01 00 00 25 c9 e2 8a 91 e4
fd fc		Natneg
1e 66 6a b2	Natneg
03		NAT-Negotiation server version (for MKWii its 0x03)
0b 		natneg step 0x0b
00 00 00 03 	sequence id from request
01 		"porttype" according to GS SDK. NN_PT_NN1 = 1, NN_PT_NN2 = 2, NN_PT_NN3 = 3 (mappings)
00 		reply flag (unknown, always empty?)
00 		unknown_1 (always empty?)
25 c9 e2 8a 	public IP address
91 e4		public port

NATIFY_REQUEST (0x0c)

This is only used during connection test (Wii settings). This is sent to wiinat.natnegX.gs.nintendowifi.net (X is a number between 1 and 3). It forces the server to answer with ERT_TEST.

fd fc 1e 66 6a b2 03 0c 00 00 03 09 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
fd fc		Natneg
1e 66 6a b2	Natneg
03		NAT-Negotiation server version (for MKWii its 0x03)
0c 		natneg step 0x0c
00 00 03 09     client-ID
01 		"porttype" according to GS SDK. NN_PT_NN1 = 1, NN_PT_NN2 = 2, NN_PT_NN3 = 3 (mappings)
60 * 0x00	unknown_5

REPORT (0x0d)

This is sent from Wii to server.

fd fc 1e 66 6a b2 03 0d 3d f1 00 71
00 00 01 00 00 00 06 00 00 00 00
6d 61 72 69 6f 6b 61 72 74 77 69 69 38*0x00
fd fc		Natneg
1e 66 6a b2	Natneg
03		NAT-Negotiation server version (for MKWii its 0x03)
0d		natneg step 0x0d
3d f1 00 71	client-ID for tracking the reply.
		Last two bytes (00 71) are last two bytes of FC of new client. 
00		porttype (0x00, 0x80 or 0x90)
00		hoststate (0x00 for guest, 0x01 for host)
01		natneg_result (0x00: error, 0x01: successful)
00 00 00 06	NAT-type (4-byte-integer, big-endian)
			0x00: No NAT,
			0x01: Firewall only,
			0x02: Full cone,
			0x03: Restricted cone,
			0x04: Port restricted cone,
			0x05: Symmetric,
			0x06: Unknown
00 00 00 00	NAT-mapping-scheme (4-byte-integer, big endian)
			0x00: Unknown,
			0x01: Private same as public,
			0x02: Consistent port,
			0x03: Incremental,
			0x04: Mixed
6d 61 72 69 \	game name (mariokartwii, 50 chars)
6f 6b 61 72 \	
74 77 69 69 \	
38 * 00

REPORT_ACK (0x0e)

fd fc 1e 66 6a b2 03 0e 3d f1 00 71 00 00 00 00 00 00 06 00 00
fd fc		Natneg
1e 66 6a b2	Natneg
03		NAT-Negotiation server version (for MKWii its 0x03)
0e		natneg step 0x0e
3d f1 00 71	client-ID for tracking the reply. Last two bytes (00 71) are last two bytes of FC of new client. 
00		porttype (0x00, 0x80 or 0x90)
00		host flag (0: client, 1: host)
00		status (0: error, 1: success)
00 00 00 06	NAT-type (same as above)
00 00		unknown_12

PREINIT (0x0f)

fd fc 1e 66 6a b2 04 0f b5 e0 95 2a 00 24 38 b2 b3 5e
fd fc		Natneg
1e 66 6a b2 	Natneg
04 		NAT-Negotiation server version
0f 		natneg step 0x0f
b5 e0 95 2a 	client-ID for tracking the reply. 
00 		hoststate
24 		state (0: Waiting for client, 1: Waiting for Matchup, 2: Ready)
38 b2 b3 5e	client-ID of other client

PREINIT_ACK (0x10)

First answer (directly after receiving PREINIT):

fd fc 1e 66 6a b2 04 10 b5 e0 95 2a 00 00 00 00 00 00
fd fc		Natneg
1e 66 6a b2 	Natneg
04 		NAT-Negotiation server version
10 		natneg step 0x10
b5 e0 95 2a 	client-ID for tracking the reply. 
00		hoststate
00 		state (0: Waiting for client, 1: Waiting for Matchup, 2: Ready)
00 00 00 00	other client-ID (or empty)

Second answer: (Send this packet with state "ready" to the other player when the other client send his "PREINIT")

fd fc 1e 66 6a b2 04 10 b5 e0 95 2a 00 00 00 00 00 00
fd fc		Natneg
1e 66 6a b2 	Natneg
04 		NAT-Negotiation server version
10 		natneg step 0x10
b5 e0 95 2a 	client-ID for tracking the reply. 
01		maybe client-index (or always empty)
02 		state (0: Waiting for client, 1: Waiting for Matchup, 2: Ready)
00 00 00 00	maybe other client ID (or always empty)

Other Servers

Template:MKWii Servers

Related Topics

Template:MKWii Network Protocol