Protocols/MSNP/MSNC/Binary Headers: Difference between revisions
No edit summary |
Animadoria (talk | contribs) No edit summary |
||
(One intermediate revision by one other user not shown) | |||
Line 1: | Line 1: | ||
{{Protocols/MSNP | {{Protocols/MSNP| | ||
section=MSNC}} | |||
=Binary headers= | =Binary headers= |
Latest revision as of 13:59, 15 May 2022
MSNP Protocol |
MSNC |
Overview • MSNObject |
Client Capabilities |
P2P protocol |
Transports • MSNSLP |
Headers |
P2Pv1 Binary headers |
P2Pv2 Binary headers |
Transfers |
Display Pictures |
Custom Emoticons |
File Transfer |
Overview |
Introduction • Terms • Clients |
Reference |
Error List • Commands • Relying Party Suite • Spotlife |
Services |
XMPP • HTTP Gateway • Tabs • Activities |
Documentation |
Development Tools • MSNP Grid |
Polygamy • URLs 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 |
Version 2 |
MSNC |
Introduction • P2P • Object Descriptor • Display Pictures • File 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.
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)