Difference between revisions of "Network Protocol/Server"

From Custom Mario Kart
Jump to navigation Jump to search
m
 
(8 intermediate revisions by 3 users not shown)
Line 1: Line 1:
Details about the communication with the N-servers:
+
== Overview ==
 +
The '''Network Protocol Server''' is a server from [[Nintendo]] that various [[DS]] and [[Wii]] games access. When entering the [[Nintendo Wi-Fi Connection]], [[Mario Kart Wii]] starts with a series of DNS queries to resolve 14 domain names, which have been stored in the table below. The different servers have different functionality, and some seems to be backup servers. It also seems that each functionality is assigned to exactly one port and will use exactly one network protocol.
  
{| class="textbox alt headline grid"
+
{{Network Protocol Servers}}
|+ List of Records
 
! Name !! Record ID !! Length !! n-server !! Description
 
|-
 
| [[MKWii_Network_Protocol/Nintendo_servers/ERROR|ERROR]] < || \error\ || ? || ?
 
| Error record sent if there was any error.
 
|-
 
| [[MKWii_Network_Protocol/Nintendo_servers/CONNECT|CONNECT]] > || 0x0900 || 18 || 248
 
| Requesting a login challenge (while connecting to WFC).
 
|-
 
| > [[MKWii_Network_Protocol/Nintendo_servers/LOGIN_CHALLENGE|LOGIN_CHALLENGE]] || \lc\1\ || 38 || 242
 
| N-server answers with challenge.
 
|-
 
| [[MKWii_Network_Protocol/Nintendo_servers/LOGIN|LOGIN]] > || \login\ || 365 || 242
 
| Wii solves the challenge and logs in at the WFC.
 
|-
 
| > [[MKWii_Network_Protocol/Nintendo_servers/LOGGED_IN|LOGGED_IN]] || \lc\2\ || ? || 242
 
| Server accepted solved Challenge and returns Sessionkey and User-IDs.
 
|-
 
| [[MKWii_Network_Protocol/Nintendo_servers/LOGOUT|LOGOUT]] > || \logout\ || 32 || 242
 
| Logout from WFC.
 
|-
 
| [[MKWii_Network_Protocol/Nintendo_servers/OTHERSLIST|OTHERSLIST]] || \otherslist\ || ? || 241
 
| Sending current friend list to N-servers and receiving an list with nicknames.
 
|-
 
| > [[MKWii_Network_Protocol/Nintendo_servers/PROFILEID|PROFILEID]] > || \pi\ || 252 || 242
 
| Sent by Nintendo if this is the first time connecting to WFC. Returns PID, UID and an signature. This is also sent after adding a new friend; then it contains user info.
 
|-
 
| [[MKWii_Network_Protocol/Nintendo_servers/RACESTATUS|RACESTATUS]] > || localip0 || ? || 242
 
| Status packet, send each minute during connection to WFC and during online races. Contains information about number of players, own IPs and own Ports
 
|-
 
| > [[MKWii_Network_Protocol/Nintendo_servers/FRIEND|FRIEND]] || \bm\100\ || 39 + status || 242
 
| N-Server returns information about friends. One to ten friends per packet. Is also sent if friend comes online and contains his IP and (later) his Port.
 
|-
 
| > [[MKWii_Network_Protocol/Nintendo_servers/FRIENDREQUEST|FRIENDREQUEST]] || \bm\2\ || 73+ || 242
 
| N-Server sends information about a user that has added the current user's friend code.
 
|-
 
| > [[MKWii_Network_Protocol/Nintendo_servers/FRIENDREGISTER|FRIENDREGISTER]] || \bm\4\ || 73+ || 242
 
| Tell the N-Server that you registered a friend code.
 
|-
 
| [[MKWii_Network_Protocol/Nintendo_servers/GETPROFILE|GETPROFILE]] > || \getprofile\ || 62 || 242
 
| Wii asks for the profile of a friend.
 
|-
 
| [[MKWii_Network_Protocol/Nintendo_servers/AUTHADD|AUTHADD]] > || \authadd\ || 95 || 242
 
| This is a prefix record for [[MKWii_Network_Protocol/Nintendo_servers/ADDBUDDY|ADDBUDDY]]
 
|-
 
| [[MKWii_Network_Protocol/Nintendo_servers/ADDBUDDY|ADDBUDDY]] > || \addbuddy\ || x * 65 || 242
 
| ?
 
|-
 
| [[MKWii_Network_Protocol/Nintendo_servers/DELBUDDY|DELBUDDY]] > || \delbuddy\ || 58+ || 242
 
| Remove someone from friend list.
 
|-
 
| ? > || \ka\ || 11 || 242
 
| Status packet send each 2 minutes
 
|-
 
| ? > || mariokartwii || 159 || 247
 
| Unknown Record containing PID (profile id) and a few keywords.
 
|-
 
| > ? || \bm\1\ || ? || 242
 
| Friend-Record with crypted message.
 
|-
 
| [[MKWii_Network_Protocol/Nintendo_servers/STATUS|STATUS]] > || \status\ || ? || 242
 
| ?
 
|-
 
| > ? || \lt\ || 35 || 242
 
| Sent each 4 minutes. ?
 
|}
 
  
This protocol is also used by the other Wii games and DS/DSi Games, only the gamename in some records changes.
+
== mariokartwii.available.gs.nintendowifi.net ==
 +
The console checks if the server is available.
  
While logging in, there is an SSL communication with naswii.nintendowifi.net.
+
<pre>09 00 00 00 00 6d 61 72 69 6f 6b 61 72 74 77 69 69 00</pre>
 +
<pre>09 is the record typ (AVAILABLE)
 +
00 00 00 00 status ("disabled services" bit field)
 +
6d 61 72 69 6f 6b \
 +
61 72 74 77 69 69 gamename ("mariokartwii")
 +
00 end</pre>
  
There is base64 encoded information:
+
If it is available, the bitfield is empty.
  
LOGIN (Wii to Nintendo):
+
<pre>fe fd 09 00 00 00 00</pre>
 +
<pre>fe fd Nintendo-Answer
 +
09 Type (AVAILABLE)
 +
00 00 00 00 status</pre>
  
 +
When the server is down permanently, bit 1 is set.
 +
 +
<pre>fe fd 09 00 00 00 01</pre>
 +
<pre>fe fd Nintendo-Answer
 +
09 Type (AVAILABLE)
 +
00 00 00 01 status</pre>
 +
 +
When the server is under maintenance, bit 2 is set.
 +
 +
<pre>fe fd 09 00 00 00 02</pre>
 +
<pre>fe fd Nintendo-Answer
 +
09 Type (AVAILABLE)
 +
00 00 00 02 status</pre>
 +
 +
== mariokartwii.sake.gs.nintendowifi.net ==
 +
For Mii requests, the game sends the following to <code>/SakeStorageServer/StorageServer.asmx</code>, with a SOAPAction header http://gamespy.net/sake/GetMyRecords.
 +
 +
<pre><?xml version="1.0" encoding="UTF-8"?>
 +
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 +
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
 +
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 +
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://gamespy.net/sake">
 +
<SOAP-ENV:Body>
 +
<ns1:GetMyRecords>
 +
<ns1:gameid>1687</ns1:gameid>
 +
<ns1:secretKey>9r3Rmy</ns1:secretKey>
 +
<ns1:loginTicket>xxxxxxxx_YYYYYYYYYY__</ns1:loginTicket>
 +
<ns1:tableid>FriendInfo</ns1:tableid>
 +
<ns1:fields><ns1:string>info</ns1:string><ns1:string>recordid</ns1:string></ns1:fields>
 +
</ns1:GetMyRecords>
 +
</SOAP-ENV:Body>
 +
</SOAP-ENV:Envelope></pre>
 +
 +
Afterwards, the requested profile ID is sent back, together with the Mii data in base64 as follows.
 +
 +
<pre><?xml version="1.0" encoding="utf-8"?>
 +
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
 +
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 +
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 +
<soap:Body>
 +
<GetMyRecordsResponse xmlns="http://gamespy.net/sake">
 +
<GetMyRecordsResult>Success</GetMyRecordsResult>
 +
<values><ArrayOfRecordValue>
 +
<RecordValue><binaryDataValue><value>$mii</value></binaryDataValue></RecordValue>
 +
<RecordValue><intValue><value>$pid</value></intValue></RecordValue>
 +
</ArrayOfRecordValue></values>
 +
</GetMyRecordsResponse>
 +
</soap:Body>
 +
</soap:Envelope></pre>
 +
 +
<code>$mii</code> is the Mii and <code>$pid</code> is the profile ID.
 +
 +
== naswii.nintendowifi.net ==
 +
It is possible to force the console to use HTTP to connect to nas.nintendowifi.net instead of naswii.nintendowifi.net.<ref>https://forum.wii-homebrew.com/index.php/Thread/51192-dev-net-ssl</ref> By adding ":81" to the URL in the main.dol, it is also possible to use another port than 80/443. While logging in, there is an SSL communication with naswii.nintendowifi.net. This is encoded in base64.
 +
 +
'''LOGIN'''
 
<pre>action=login
 
<pre>action=login
gsbrcd=RMCJ2leohni Any nickname?
+
gsbrcd=RMCJ2abcdef The second part of the unique nick name.
userid=1786673827498 Any ID, but not the friend code or profile / user id
+
userid=1739273526102 The decoded first part of the unique nick name.
ingamesn= n o  n a m e Any nickname / Mii name?
+
ingamesn= n o  n a m e For Wii its the Mii name, for DS its the User name
sdkver=001000 Always binary "8" for MKWii
+
sdkver=001000 Always "1.0" for MKWii (two 3-char decimal numbers)
 
gamecd=RMCE ID4 of Game
 
gamecd=RMCE ID4 of Game
 
makercd=01 last two digits of ID6
 
makercd=01 last two digits of ID6
 
unitcd=1 ?
 
unitcd=1 ?
macadr=0017ab2923be The MAC-Adress of the Wii
+
macadr=001712345678 The WLAN-MAC-Adress of the Wii
lang=01 Maybe a language code ?
+
lang=01 A language code. English is 01, German is 02
devtime=140228160425 Unix timestamp of wii time
+
devtime=140228160425 Wii date/time in Format YYMMDDhhmmss
csnum=LU519608598 Wii S/N
+
csnum=LU123456789 Wii S/N
cfc=7615213554627182 Any code, maybe wii friend code
+
cfc=1234567890123456 Wii FC
region=01 Any region identifier</pre>
+
region=01 Any region identifier. Maybe the same as the language code</pre>
  
ACCTCREATE (Wii to Nintendo)
+
'''ACCTCREATE'''
  
 
<pre>action=acctcreate
 
<pre>action=acctcreate
sdkver=001000 Always binary "8" for MKWii
+
sdkver=001000 Always "1.0" for MKWii (two 3-char decimal numbers)
 
gamecd=RMCP ID4 of Game
 
gamecd=RMCP ID4 of Game
 
makercd=01 last two digits of ID6
 
makercd=01 last two digits of ID6
 
unitcd=1 ?
 
unitcd=1 ?
macadr=0017ab2923be The Wiis MAC-Adress
+
macadr=001712345678 The Wiis WLAN-MAC-Adress
lang=02 Maybe a language code ?
+
lang=02 A language code. English is 01, German is 02.
devtime=140304203139 Unix timestamp of wii time
+
devtime=140304203139 Wii date/time in Format YYMMDDhhmmss
csnum=LE632014481 Wii S/N
+
csnum=LU123456789 Wii S/N
cfc=7615213554627182 Any code, maybe wii friend code
+
cfc=1234567890123456 Wii FC
region=02 Any region identifier</pre>
+
region=02 Any region identifier. May be the same as the language code</pre>
  
Nintendo to Wii:
+
'''RESPONSE'''
  
 
<pre>challenge=687TF0EG Any challenge
 
<pre>challenge=687TF0EG Any challenge
 
locator=gamespy.com ?
 
locator=gamespy.com ?
 
retry=0 count of retries
 
retry=0 count of retries
returncd=00 ?
+
returncd=00 returncode. Bigger than 99, lower than 1000: Error message 20XXX.
 +
                        Bigger than 1000: Turn off Wii
 
token=... Same token as during LOGIN
 
token=... Same token as during LOGIN
 
datetime=20140228210452 Server date/time in format YYYYMMDDhhmmss</pre>
 
datetime=20140228210452 Server date/time in format YYYYMMDDhhmmss</pre>
  
The values "macadr" and "cfc" are the same in both dumps, but maybe this is a fault of dolphin.
+
In DS games, the following data is also present in '''ACCTCREATE'''.
 +
 
 +
<pre>
 +
apinfo=XX-0000000-00 XX is 00 for the first WiFi-Connection, 01 for the second,
 +
                        02 for the third and probably 03 for the Nintendo USB Connector
 +
devname=... Username in UTF16-LE
 +
passwd=... Unknown three-digit code
 +
bssid=000d0bf85370 WLAN-MAC from WLAN-AP
 +
birth=071b Two bytes Birthdate. First byte is Month (July), second Day (27th)</pre>
 +
 
 +
== dls1.nintendowifi.net ==
 +
This server is not used by [[Mario Kart Wii]]. An example of DLS1 usage is Pokémon's [[bulbapedia:Mystery Gift|Mystery Gift]]s. Once authenticated via [[NAS]], the game sends the following encoded in base64:
 +
 
 +
<pre>
 +
sdkver=002002
 +
userid=2022983770208
 +
passwd=172
 +
bssid=A1B2C3D4E5F6
 +
apinfo=01:0000000-00
 +
gamecd=CPUE
 +
makercd=01
 +
unitcd=0
 +
macadr=345678901234
 +
lang=01
 +
birth=MMDD
 +
devtime=150813185742
 +
devname=B i l l y  H
 +
action=SVCLOC
 +
svc=9000
 +
</pre>
 +
 
 +
where
 +
* <code>bssid</code> is your Wi-Fi's BSSID,
 +
* <code>macadr</code> is your MAC address,
 +
* <code>devname</code> is your name in UTF-16,
 +
* <code>APInfo</code> is which access point it uses.
 +
 
 +
The server sends back the following:
 +
 
 +
<pre>
 +
retry=0
 +
returncd=007
 +
token=NDS/SVCLOC/TOKEN/123.456.789.000|abcdefghijkl
 +
servicetoken=NDS/SVCLOC/TOKEN/123.456.789.000|abcdefghijkl
 +
statusdata=Y
 +
svchost=dls2.pokeacer.xyz
 +
datetime=20150813195801
 +
</pre>
 +
 
 +
where <code>svchost</code> is the DLS1 server to connect to.
 +
 
 +
The client then sends a request to <code>/download</code>:
 +
 
 +
<pre>
 +
gamecd=CPUE
 +
rhgamecd=CPUE
 +
passwd=DwuCXmdJfPVLBnKA
 +
token=NDS/SVCLOC/TOKEN/123.456.789.000|abcdefghijkl
 +
userid=2022983770208
 +
macadr=345678901234
 +
action=count
 +
apinfo=01:0000000-00
 +
</pre>
 +
 
 +
where <code>action=count</code> means to count how many files are on the server. However, in the case of the Pokémon example, the server must lie and pick either a random one in the folder (what public implementations do) or list the only file in the server (what Nintendo probably did).
 +
 
 +
The server then responds with how many (in this case one) files are present and then the client sends:
 +
 
 +
<pre>
 +
gamecd=CPUE
 +
rhgamecd=CPUE
 +
passwd=DwuCXmdJfPVLBnKA
 +
token=NDS/SVCLOC/TOKEN/123.456.789.000|abcdefghijkl
 +
userid=2022983770208
 +
macadr=345678901234
 +
action=list
 +
apinfo=01:0000000-00
 +
offset=0
 +
num=10
 +
</pre>
 +
 
 +
The response of the server is then the correct filename, some NULL characters and a number.
 +
 
 +
The game finally sends:
 +
 
 +
<pre>
 +
gamecd=CPUE
 +
rhgamecd=CPUE
 +
passwd=DwuCXmdJfPVLBnKA
 +
token=NDS/SVCLOC/TOKEN/123.456.789.000|abcdefghijkl
 +
userid=2022983770208
 +
macadr=345678901234
 +
action=contents
 +
apinfo=01:0000000-00
 +
contents=21dppUS.myg
 +
</pre>
 +
 
 +
to which the server sends the file.
 +
 
 +
== References ==
 +
<references/>
 +
 
 +
{{Network Protocol}}
 +
[[Category:Network Protocol|S]]

Latest revision as of 13:09, 30 April 2023

Overview

The Network Protocol Server is a server from Nintendo that various DS and Wii games access. When entering the Nintendo Wi-Fi Connection, Mario Kart Wii starts with a series of DNS queries to resolve 14 domain names, which have been stored in the table below. The different servers have different functionality, and some seems to be backup servers. It also seems that each functionality is assigned to exactly one port and will use exactly one network protocol.

Network Protocol Servers
DNS Name IP Address Port Protocol Description
gamestats.gs.nintendowifi.net
mariokartwii.gamestats.gs.nintendowifi.net
69.10.30.240 29920 These are looked up, but never used.
gamestats2.gs.nintendowifi.net
mariokartwii.gamestats2.gs.nintendowifi.net
69.10.30.234 TCP These are looked up, but never used.
gpcm.gs.nintendowifi.net 69.10.30.242 29900 TCP This connection is used to manage friends and to inform about one's status.
gpsp.gs.nintendowifi.net 69.10.30.241 29901 TCP This server exchanges profile IDs into nicks.
mariokartwii.available.gs.nintendowifi.net
mariokartwii.master.gs.nintendowifi.net
69.10.30.248 27900 UDP This checks if the server is available.
mariokartwii.ms19.gs.nintendowifi.net 69.10.30.247 28910 TCP This server handles database requests for online matchmaking.
mariokartwii.natneg1.gs.nintendowifi.net 69.10.30.254 27901 UDP NATNEG is a way to bypass NAT and firewalls.
mariokartwii.natneg2.gs.nintendowifi.net 69.10.30.253 27901 UDP NATNEG is a way to bypass NAT and firewalls.
mariokartwii.natneg3.gs.nintendowifi.net 69.10.30.252 27901 UDP NATNEG is a way to bypass NAT and firewalls.
mariokartwii.sake.gs.nintendowifi.net 69.10.24.119 443 TCP/HTTP(S) This server handles Mii exchanges and ghost up- and downloads.
naswii.nintendowifi.net 192.195.204.143
69.25.139.143
443 TCP/HTTP(S) The authority DNS server delivers randomly both IP addresses with a time to live of 30 seconds to support a kind of load balancing.
mariokartwii.race.gs.nintendowifi.net 69.10.24.125 443 TCP/HTTP(S) This server is used for Time Trial and Competition leaderboards and the actual competition distribution.


mariokartwii.available.gs.nintendowifi.net

The console checks if the server is available.

09 00 00 00 00 6d 61 72 69 6f 6b 61 72 74 77 69 69 00
09 			is the record typ (AVAILABLE)
00 00 00 00		status ("disabled services" bit field)
6d 61 72 69 6f 6b \
61 72 74 77 69 69	gamename ("mariokartwii")
00 			end

If it is available, the bitfield is empty.

fe fd 09 00 00 00 00
fe fd		Nintendo-Answer
09		Type (AVAILABLE)
00 00 00 00	status

When the server is down permanently, bit 1 is set.

fe fd 09 00 00 00 01
fe fd		Nintendo-Answer
09		Type (AVAILABLE)
00 00 00 01	status

When the server is under maintenance, bit 2 is set.

fe fd 09 00 00 00 02
fe fd		Nintendo-Answer
09		Type (AVAILABLE)
00 00 00 02	status

mariokartwii.sake.gs.nintendowifi.net

For Mii requests, the game sends the following to /SakeStorageServer/StorageServer.asmx, with a SOAPAction header http://gamespy.net/sake/GetMyRecords.

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
   xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://gamespy.net/sake">
<SOAP-ENV:Body>
<ns1:GetMyRecords>
<ns1:gameid>1687</ns1:gameid>
<ns1:secretKey>9r3Rmy</ns1:secretKey>
<ns1:loginTicket>xxxxxxxx_YYYYYYYYYY__</ns1:loginTicket>
<ns1:tableid>FriendInfo</ns1:tableid>
<ns1:fields><ns1:string>info</ns1:string><ns1:string>recordid</ns1:string></ns1:fields>
</ns1:GetMyRecords>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Afterwards, the requested profile ID is sent back, together with the Mii data in base64 as follows.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetMyRecordsResponse xmlns="http://gamespy.net/sake">
<GetMyRecordsResult>Success</GetMyRecordsResult>
<values><ArrayOfRecordValue>
<RecordValue><binaryDataValue><value>$mii</value></binaryDataValue></RecordValue>
<RecordValue><intValue><value>$pid</value></intValue></RecordValue>
</ArrayOfRecordValue></values>
</GetMyRecordsResponse>
</soap:Body>
</soap:Envelope>

$mii is the Mii and $pid is the profile ID.

naswii.nintendowifi.net

It is possible to force the console to use HTTP to connect to nas.nintendowifi.net instead of naswii.nintendowifi.net.[1] By adding ":81" to the URL in the main.dol, it is also possible to use another port than 80/443. While logging in, there is an SSL communication with naswii.nintendowifi.net. This is encoded in base64.

LOGIN

action=login
gsbrcd=RMCJ2abcdef	The second part of the unique nick name. 
userid=1739273526102	The decoded first part of the unique nick name. 
ingamesn= n o   n a m e	For Wii its the Mii name, for DS its the User name
sdkver=001000		Always "1.0" for MKWii (two 3-char decimal numbers)
gamecd=RMCE		ID4 of Game
makercd=01		last two digits of ID6
unitcd=1		?
macadr=001712345678	The WLAN-MAC-Adress of the Wii
lang=01			A language code. English is 01, German is 02
devtime=140228160425	Wii date/time in Format YYMMDDhhmmss
csnum=LU123456789	Wii S/N
cfc=1234567890123456	Wii FC
region=01		Any region identifier. Maybe the same as the language code

ACCTCREATE

action=acctcreate
sdkver=001000		Always "1.0" for MKWii (two 3-char decimal numbers)
gamecd=RMCP		ID4 of Game
makercd=01		last two digits of ID6
unitcd=1		?
macadr=001712345678	The Wiis WLAN-MAC-Adress
lang=02			A language code. English is 01, German is 02. 
devtime=140304203139	Wii date/time in Format YYMMDDhhmmss
csnum=LU123456789	Wii S/N
cfc=1234567890123456	Wii FC
region=02		Any region identifier. May be the same as the language code

RESPONSE

challenge=687TF0EG	Any challenge
locator=gamespy.com	?
retry=0			count of retries
returncd=00		returncode. Bigger than 99, lower than 1000: Error message 20XXX.
                        Bigger than 1000: Turn off Wii
token=...		Same token as during LOGIN
datetime=20140228210452	Server date/time in format YYYYMMDDhhmmss

In DS games, the following data is also present in ACCTCREATE.

apinfo=XX-0000000-00	XX is 00 for the first WiFi-Connection, 01 for the second,
                        02 for the third and probably 03 for the Nintendo USB Connector
devname=...		Username in UTF16-LE
passwd=...		Unknown three-digit code
bssid=000d0bf85370	WLAN-MAC from WLAN-AP
birth=071b		Two bytes Birthdate. First byte is Month (July), second Day (27th)

dls1.nintendowifi.net

This server is not used by Mario Kart Wii. An example of DLS1 usage is Pokémon's Mystery Gifts. Once authenticated via NAS, the game sends the following encoded in base64:

sdkver=002002
userid=2022983770208
passwd=172
bssid=A1B2C3D4E5F6
apinfo=01:0000000-00
gamecd=CPUE
makercd=01
unitcd=0
macadr=345678901234
lang=01
birth=MMDD
devtime=150813185742
devname=B i l l y   H
action=SVCLOC
svc=9000

where

  • bssid is your Wi-Fi's BSSID,
  • macadr is your MAC address,
  • devname is your name in UTF-16,
  • APInfo is which access point it uses.

The server sends back the following:

retry=0
returncd=007
token=NDS/SVCLOC/TOKEN/123.456.789.000|abcdefghijkl
servicetoken=NDS/SVCLOC/TOKEN/123.456.789.000|abcdefghijkl
statusdata=Y
svchost=dls2.pokeacer.xyz
datetime=20150813195801

where svchost is the DLS1 server to connect to.

The client then sends a request to /download:

gamecd=CPUE
rhgamecd=CPUE
passwd=DwuCXmdJfPVLBnKA
token=NDS/SVCLOC/TOKEN/123.456.789.000|abcdefghijkl
userid=2022983770208
macadr=345678901234
action=count
apinfo=01:0000000-00

where action=count means to count how many files are on the server. However, in the case of the Pokémon example, the server must lie and pick either a random one in the folder (what public implementations do) or list the only file in the server (what Nintendo probably did).

The server then responds with how many (in this case one) files are present and then the client sends:

gamecd=CPUE
rhgamecd=CPUE
passwd=DwuCXmdJfPVLBnKA
token=NDS/SVCLOC/TOKEN/123.456.789.000|abcdefghijkl
userid=2022983770208
macadr=345678901234
action=list
apinfo=01:0000000-00
offset=0
num=10

The response of the server is then the correct filename, some NULL characters and a number.

The game finally sends:

gamecd=CPUE
rhgamecd=CPUE
passwd=DwuCXmdJfPVLBnKA
token=NDS/SVCLOC/TOKEN/123.456.789.000|abcdefghijkl
userid=2022983770208
macadr=345678901234
action=contents
apinfo=01:0000000-00
contents=21dppUS.myg

to which the server sends the file.

References