S>C 0x3E SID_LOGONREALMEX
Transport Layer: | Transmission Control Protocol (TCP) |
---|---|
Application Layer: | Battle.net v1 TCP Messages (SID) |
Message Id: | 0x3E |
Message Name: | SID_LOGONREALMEX |
Direction: | Server to Client |
Options: | In Research |
Used By: | Diablo II, Diablo II Lord of Destruction |
Message Format: (does not include protocol header) |
|
Remarks
This packet supplies the data necessary to connect to an MCP server. The cookie value is defined in the first UINT32 of SID_LOGONREALMEX and is simply returned by Battle.net. If the length of the message (not including header) is greater than 8, the client should continue to logon to the MCP. Otherwise, the Status field is interpreted as an error code:
0x80000001
: Realm is unavailable0x80000002
: Realm logon failed
Any other value indicates failure.
The first part of the MCP Chunk that must be sent to the MCP server includes the Status and Cookie UINT32S, making MCP Chunk 1 the first 4 UINT32S of the packet.
There used to be a UINT16 at the end of this packet, which was apparently random.
As of D2 1.14d, the packet structure is different, but is backwards-compatible with the previous structure.
Comments
Credit goes to l2k-Shadow for the following information:
To get the port # from the port DWORD, use the ntohs function.
Example code in C++:
#include <windows.h>
#include <winsock2.h>
#include <iostream.h>
#pragma comment(lib, "ws2_32")
void main()
{
char s[] = "\x17\xe0\x00\x00";
DWORD d = 0;
memcpy(&d, s, 4);
cout << ntohs(d) << endl;
}
Credits goes to Chriso.de for VB conversion:
Public Declare Function ntohs Lib "ws2_32" (ByVal netshort As Long) As Long
' Get the port
Port = ntohs(r.GetInt32())
Diablo 2 realms went down the morning of 9/7/08, and when they came back up, this packet had changed, breaking a few clientless bots.
The (WORD) Unknown from this packet HAS been removed entirely.
Hmm, strange. Guess we'll never know what it was.
How to get the port # from DWORD with Python:
socket.ntohs(struct.unpack("< i", "\x17\xe0\x00\x00")[0])
How to convert port to DWORD with Python:
struct.pack("< i", socket.htons(6112))
Remove the space between < and i, these docs dont parse code comments well.
How to get the IP from DWORD with Python:
socket.inet_ntoa("\x3f\xf1\x53\x12")
How to convert IP to DWORD with Python:
socket.inet_aton("63.241.83.18")
Remove the extra quotation marks, these docs dont parse code comments well.
It's important to note that bot the IP and the Port are both in big endian byte order. It also appears that the port is a 2 byte value followed by and unknown of 2 bytes.
As of 1.14d, the packet structure is significantly different.
UINT8[16] Unknown 1 (MD5?)
UINT32 IP (Big Endian)
UINT32 Port (Big endian)
UINT8[40] Unknown 2 (SHA-1?)
UINT8[9] Unknown 3 (Padding?)