Since March 10, 2003 - Version 2
hypothetic.org

MSN Messenger Protocol

Protocols - File Transfer

Back To Normal Layout

File transfer

Though not technically a part of the MSN Messenger protocol, a file transfer protocol called "MSNFTP" is included in the official client. This protocol is unrelated to "FTP", or any other file transfer protocol.

Overview

Several very similar terms are used in MSNFTP, which can be make it very confusing to read this page. The "sender" and "receiver" is the computer which sends and receives the file, respectively. The "server" and "client" is the computer which initiates and receives the TCP connection, respectively. A messages is "transmitted" (so as not to confuse "sending a message" with "sending the file").

During the invitation stage, the messenger clients will agree on which computer should be the server and which the client, which computer should be sender and which the receiver, what the file to be transferred is called, and an authentication cookie for the session. The sender is usually the server, but may ask the receiver to serve.

Once the client has connected to the server, MSNFTP begins with the two computers exchanging lines of text much like in an NS or SB conversation. In this initial stage, the computers negotiate a protocol, the receiver gives its passport and the authentication cookie, and the sender replies with the size of the file. Then, the sender sends the file in fixed-length blocks of binary data. The receiver can cancel the transfer at any time.

Establishing the connection

During the invitation stage, the computers agreed on either one or two IP addresses and ports the client should connect to. If only one IP address and port was given, the client should connect to that address and port, while the server should listen for connections on the port. If two addresses and ports were given, the server should listen for connections on both ports, while the client should simultaneously attempt to connect to the primary and secondary IP addresses and ports. As soon as one connection has been established, both computers should stop attempting to connect on the other port.

Binary data

This section discusses binary data, how to transmit and receive it. If you're already familiar with binary, you can safely ignore this section.

Ultimately, all computer information is just a series of 1s and 0s. A byte is a series of eight 1s and 0s, so a byte can be in any one of 256 (2^8) different states. In a text-based protocol like MSN Messenger, bytes are interpreted as characters of information according to some standard - usually ASCII. In a binary protocol, bytes are interpreted as something else - numbers between 0 and 255, shades of grey between black and white, reasons for a program crashing, etc.

It's most popular to interpret bytes of data as numbers, often in base 16 ("hexadecimal") instead of base 10 ("decimal"). To make this page easier to read, I'll use decimal, but hexadecimal numbers are used a lot in computing - for example, in plaintext message colour codes. Some programmers like to write things in hexadecimal because (once you get used to it) it's much easier to convert between hexadecimal and binary in your head.

You should consult your language's documentation about how it handles binary data. One important thing to check is that many programming languages (e.g. C and Visual Basic) use the same data type to represent a byte that they use to represent a character, but don't treat bytes and characters the same way - for example, the character '0' is not the same as the number 0. In Visual Basic, for example, you have to do asc(0) to get the ASCII character equivalent to the number 0, and val('0') to get the numerical value of the ASCII character 0.

Protocol - text section

The text section resembles the authentication step of logging into a notification server, except that there are no transaction IDs, and if either side transmits an invalid command, the other side should just close the connection without transmitting an error message.

First, the receiver transmits a VER command with the versions of the MSNFTP protocol it supports as parameters. The official client only supports MSNFTP. The sender replies with a VER command containing the chosen protocol.

Then, the receiver transmits a USR command with the username as the first parameter and authentication cookie as the second. The sender replies with a FIL command with the size of the file in bytes as the only parameter. The official client uses this instead of the size given during the invitation stage.

The receiver transmits a TFR command to indicate that it is ready to receive. At this point, the sender switches to binary for the rest of the session.

At some point after that, the receiver must transmit BYE with a single numeric argument indicating the result of the file transfer. The following values are allowed:

2147942405
Failure: receiver is out of disk space
2164261682
Failure: receiver canceled the transfer
2164261683
Failure: sender has canceled the transfer
2164261694
Failure: connection is blocked
16777987
Success
16777989
Success

As a special case, CCL should be sent with no argument instead of BYE 2164261682. In practice, only BYE 16777989 and CCL have ever been observed, and the official client's support for other codes is shabby at best.

Once the sender has finished sending, it should wait for the receiver to transmit a BYE command. If the sender does not receive a BYE quickly enough (within about 1 minute in the official client), it will transmit an invitation command in the switchboard session with "Invitation-Command: CANCEL" and "Cancel-Code: FTTIMEOUT". The sender may close the connection at any time after it has finished sending.

Protocol - binary section

An MSNFTP block consists of a header and a body. The header specifies whether the file has been completely sent, and (if not) the number of bytes that will be sent in the body of this block. The body contains the specified number of bytes from the file.

The header is three bytes long. If the file has not been completely transmitted, the first byte of the header will be 0, and the second two bytes of the header will specify the length of the body - the length is equal to the value of the second byte plus 256 times the value of the third byte. So, for example, if the number of bytes in the body is 2045 (the default length in the official client), the value of second byte would be 253 and the value of the third byte would be 7 (253 + 7*256 = 2045). the specified number of bytes follow in the body. Once the file has been completely transmitted, a final block is sent in which the first byte of the header is 1, the second two bytes are 0, and the body is empty.

For example, if you wanted to transmit a 13-byte long file containing the string "Hello, world!", the steps you might go through are:

  1. Generate the first block.
  2. Transmit the first block.
  3. Check whether the receiver has transmitted a BYE or CCL message. If so, close the socket.
  4. Generate the second block.
  5. Transmit the second block
  6. The file is now complete.
  7. Wait up to a minute for the receiver to transmit BYE or CCL, then close the connection

Example sessions

Here is an example of a successful transfer (note that italics represent binary data):

<o> Incoming Connection on Port: 6891

<<< VER MYPROTO MSNFTP

>>> VER MSNFTP

<<< USR myname@msn.com 93301

>>> FIL 13

<<< TFR

>>> 0, 13, 0, 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33

>>> 1, 0, 0

<<< BYE 16777989

And here is a failed negotiation:

<o> Incoming Connection on Port: 6891

<<< VER MYPROTO

<o> Disconnect

Copyright ©2002-2003 to Mike Mintz.
<http://www.mikemintz.com/>