Protocols/MSNP/MSNC/Binary Headers

From NINA Wiki
Jump to navigation Jump to search
MSNP Protocol
MSNC
OverviewMSNObject
Client Capabilities
P2P protocol
TransportsMSNSLP
Headers
P2Pv1 Binary headers
P2Pv2 Binary headers
Transfers
Display Pictures
Custom Emoticons
File Transfer
Overview
IntroductionTermsClients
Reference
Error ListCommandsRelaying Party SuiteSpotlife
Services
XMPPHTTP GatewayTabsActivities
Documentation
Development ToolsMSNP Grid
PolygamyURLs used by MSN
Documents
Protocol Versions
Version 21
Version 18
Version 16
Version 15
Version 14
Version 13
Version 12
Version 11
Version 9
Version 8
MSNC
IntroductionP2PObject DescriptorDisplay PicturesFile Transfer
Scenarios
Microsoft Messenger for Mac
MSNP on WebTV (MSNTV)

Binary headers

P2P messages consist of a 48-byte binary header, zero or more bytes of content, and at the end a 4-byte binary footer.

The 48-byte binary header consists of 6 DWORDs and 3 QWORDS, which are all in little endian (little end first) order, where a DWORD is a 32-bit (4 byte) unsigned integer and QWORD is 64 bits (8 bytes).

Fields in the table are index, byte offset, data type, name used for the field in this documentation, and description.

1 0 DWORD SessionID The SessionID, which is zero when the Clients are negotiating about the session.
2 4 DWORD Identifier The first message you receive from the other client is the BaseIndentifier, the other messages contains a number near the BaseIdentifier.
3 8 QWORD Data offset Explained under Splitting big messages. Most often the messages are not split, and this value is 0.
4 16 QWORD Total data size Case 1: The byte size of all data sent between the header and footer of all of the message parts. This is the same independent of how many pieces the message is split in. Case 2: If this is an acknowledgement, this field is a copy of the same field in the message acknowledged. Sending acknowledgements
5 24 DWORD Message length The byte size of the data between the header and footer of this particular message.
6 28 DWORD Flag Identifies the message type. See the flags section
7 32 DWORD Acknowledged identifier If the SessionID field is zero and the data doesn't contain the SessionID then this field contains the Identifier of the previous received message. If the data contains the SessionID or if the SessionID field is non-zero then this field is just some random generated number.
8 36 DWORD Acknowledged unique ID In case the message is an acknowledgement, this is a copy of the previous field of the acknowledged message. Else this is 0.
9 40 QWORD Acknowledged data size In case the message is an acknowledgement, this is a copy of the Total data size field of the acknowledged message. Else this is 0.

Flags

The flags field in binary header can take the following values:

  • 0x0: no flags specified
  • 0x1: chunk out-of-order
  • 0x2: acknowledgement
  • 0x4: there is a pending invite
  • 0x8: error on the binary level
  • 0x20: display picture/custom emoticon data
  • 0x01000030: file transfer data

Splitting big messages

When the content of the message between the binary header and footer is larger then 1202 characters (or 1352 in case of a Direct Connection), the data must be sent in separate messages, each a complete P2P message with a Content-Type, P2P-dest, binary header and binary footer. The message is acknowledged from the receiving client only when all parts have been received, with the total size of the content as acknowledged data size. Here is the binary header you should use when splitting messages:

  • SessionID: The same Session ID as you've used when handshaking
  • Identifier: It must be the identifier used in the "data preparation" message + 1. It will stay the same for all parts.
  • Data Offset: Amount of data (in bytes) that has been sent up to this part.
  • Total data size: Amount of data (in bytes) that will be sent.
  • Message length: Amount of data (in bytes) in this part.
  • Message type: Type of message, see the upper paragraph.
  • Acknowledged identifier: Random number.
  • Identifier: 0
  • Acknowledged data size: 0

Sending acknowledgements

When a client sends you a P2P-message, you should always reply with a sort of Acknowledgement Message (otherwise the official MSN Client will probably refuse your datum). Let's suppose that you've received and decoded a certain binary header. The acknowledgement message you can send has the following binary header:

  • SessionID: Session ID of the received binary header
  • Identifier: You can simply invert the identifier in the received binary header (~identifier in C++)
  • Data Offset: 0
  • Total data size: Same as the "total data size" field of the received binary header
  • Message length: 0
  • Message type: 2
  • Acknowledged identifier: You can simply add one to the identifier in the received binary header
  • Identifier: Identifier of the received binary header
  • Acknowledged data size: Same as the "total data size" field of the received binary header

The footer is 4-bytes long and only contains 0s.

Note that when messages are split, you should only send one acknowledgement when the last part of the split message is received.

Footer

The 4-byte binary footer consists of 1 DWORD which is in big endian (big end first) order and that field represents the ApplicationIdentifier (AppID). If this field is zero, then the clients are negotiating about the session. The ApplicationIdentifier is 0x1 for display picture and emoticon transfer, 0x2 for file transfers, and for games it's specified by the start nenu code.

P2Pv2 Binary Headers -- WLM 2009

When the client Alice logs in using MSNP18, and starts a session to another WLM 2009 client Bob (I believe Alice knows the client type of Bob by the GUID that is attached to the email in Bob's JOI command) then the file transfer binary header is substantially changed.

All data is Big Endian. The binary header size is dynamic - It can be 8(0x08) and 24(0x18) The new P2P protocol allways(?) has header and message part.

For all of them - (WORD is 2 bytes long)

1 BYTE HL Length of header.
2 BYTE OP Operation code. 0: None, 2: Ack, 3: Init session.
3 WORD ML Message length without header length. (but included the header's message length)
4 DWORD BaseID Initially random (?) To get the next one add the payload length.
TLVs BYTE[HL-8] TLV Data TLV list consists of TLV-encoded pairs (type, length, value). A whole TLV list is padded with zeros to fit 4-byte boundary. If header length(HL) greater then 8 TLVs = ReadBytes(HeaderLength - 8) ; else process data packet (D). TLVs: T=0x1(1) L=0xc(12): IPv6 address of sender/receiver. T=0x2(2) L=0x4(4): ACK identifier.
DH DHL Data Header
BYTE DHL: Data header length
BYTE TFCombination: 0x1=First, 0x4=Msn object (display picture, emoticon etc), 0x6=File transfer
WORD PackageNumber: Package number
DWORD SessionID: Session Identifier
BYTE[DHL-8] Data packets TLVs: if (DHL>8) then read bytes(DHL - 8). T=0x1(1) L=0x8(8): Data remaining.
D ML-DHL Data Packet SLP messsage or data packet
F DWORD Footer The footer.


First P2P message

H: 18 03 05 4e 13 63 d5 a0 01 0c 00 02 00 00 00 0e 76 2d 0f 01 00 00 00 00 DH: 08 01 00 00 00 00 00 00 D: SLPMessage

All type of header has the follow fields:

1 0x18 Length of header 24
2 0x03 Operation code The first p2p message. Initialize session.
3 0x05 0x4e Size of message 1358 = 1350+8(0x08)
4 0x13 0x63 0xd5 0xa0 Base ID The next Base ID += Size of message
TLVs 01 0c 00020000 000e762d 0f010000 (00 00) TLV data T=01,L=12,V=00020000 000e762d 0f010000. (00 00 = Padded with zeros to fit 4-byte boundary.)
DH 08 01 00 00 00 00 00 00 Data Header 08=DataHeaderLength, 01=TFCombination, 00 00=PackageNumber, 00 00 00 00 = Session ID, No TLV because DataHeaderLength=8, not greater then 8. So process data (SLP)
D SLP SLP SLP Message


An acknowledgement

H: 08 02 00 00 93 e7 20 56 DH: (no data) D: (no data) F: 00 00 00 00

1 0x08 Length of header 8
2 0x02 Operation code Acknowledgement
3 0x00 0x00 Size of message 0
4 0x93 0xe7 0x20 0x56 Base ID AckIdentifier = Base ID + Size of Message
TLVs (No tlv data) TLVs Length of header <= 8, so no TLVs in this sample package.
DH (no data) Data Header Size of message is 0.
D (no data) Data Size of message is 0.
F 0x00 0x00 0x00 0x00 Footer Footer is 0 (always).


File Transfer

H: 08 00 05 70 13 63 da ee DH: 14 07 00 00 d1 c5 26 da 01 08 00 00 00 00 00 02 04 1c 00 00 D: ...

1 0x08 Length of header 8
2 0x00 Operation code None
3 0x05 0x70 Size of message 1392 = 1372+20(0x14)
4 0x13 0x63 0xda 0xee Base ID The next Base ID += Size of message
TLVs (No tlv data) TLVs Length of header <= 8, so no TLVs in this sample package.
DH 14 07 0000 d1c526da 01 08 00000000 0002041c 0000 Data Header 0x14(20)=DataHeaderLength, 0x7=TFCombination(The first file transfer message. 0x06 is all other file transfer message), 0000=PackageNumber, d1 c5 26 da = Session ID from SLP, T(01) L(08) V(00 00 00 00 00 02 04 1c - data remaining) Padding(00 00)
D Data Data File data


Display Picture

H: 08 00 05 70 03 a3 da ee DH: 14 05 00 00 d1 c5 26 dc 01 08 00 00 00 00 00 00 34 f5 00 00 D: ...

1 0x08 Length of header 8
2 0x00 Operation code None
3 0x05 0x70 Size of message 1392 = 1372+20(0x14)
4 0x03 0xa3 0xda 0xee Base ID The next Base ID += Size of message
TLVs (No tlv data) TLVs Length of header <= 8, so no TLVs in this sample package.
DH 14 05 0000 d1c526da 01 08 00000000 0002041c 0000 Data Header 0x14(20)=DataHeaderLength, 0x5=TFCombination(The first display picture message. 0x04 is all other display picture message), 0000=PackageNumber, d1 c5 26 da = Session ID from SLP, T(01) L(08) V(00 00 00 00 00 00 34 f5 - data remaining) Padding(00 00)
D Data Data Picture data

Before the start of the file transfer, bytes 10-13 contain the BaseIdentifier of the MSG we are replying to.

When transferring file data, the header size is 28 bytes. Unless it's the last chunk - then its 16 bytes, because the Remaining size field isn't in header's message.

For more information

P2Pv1 and P2Pv2 Header Definitions

Binary header research on MSNC10 (The new P2P protocol used in WLM 2009 and MSNP18)