home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 13 / AACD13.ISO / AACD / Online / StrICQ / Src / ICQTCPSpec.txt < prev    next >
Text File  |  1999-11-30  |  35KB  |  693 lines

  1.  
  2.                     ICQ TCP Protocol as used by STRICQ
  3.                                      
  4.                     Written By:  Douglas F. McLaughlin
  5.                                      
  6.                   $VER:  STRICQ TCP Protocol 0.99a 11.30.99
  7.                                      
  8.                                      
  9.                              Table of Contents
  10.  
  11. 1.  Introduction
  12. 2.  Starting with UDP
  13. 3.  Switch to TCP
  14. 4.  The TCP Init Packet
  15. 5.  The TCP Message Packet
  16. 6.  The Message ACK Packet
  17. 7.  TCP Message Related #define's
  18. 8.  Other Forms of the TCP Message Packet
  19. 9.  Reverse TCP Connections
  20. 10. File Direct Protocol
  21. 11. Chat Mode Protocol
  22.  
  23.  
  24.                               1. Introduction
  25.  
  26.      This text will hopefully help explain a lot of the details of ICQ's
  27. TCP protocol version 2 (v2).  Not all available codes and packets have been
  28. completely deciphered, however, these packets are VERY rare and therefore
  29. hard to intuit a specific meaning.
  30.  
  31.      First of all, this text would not be possible were it not for the help
  32. and hard work of a few other people.  A small portion of the DEFINEs are
  33. based upon work done by Matt Smith author of micq.  Most of the basic
  34. format of the TCP Message and Chat packets were worked out by the author of
  35. Licq (whose name I can't remember right now.)  The basis for the TCP File
  36. Direct packets comes from the source code icqfile.cpp.  This document and
  37. the final meshing of all this information into one protocol was done by
  38. Douglas F. McLaughlin author of STRICQ for the Amiga computer.  (And
  39. Mirabilis said it couldn't be done!)  Please do not spread this text
  40. without applying full credit to its author and the author's sources as
  41. mentioned in the paragraph.
  42.      
  43.      Finally, this document assumes a good working knowledge of opening and
  44. using TCP sockets and how to manage multiple open sockets at once.  This
  45. includes how to use listen() sockets.
  46.  
  47.  
  48.                            2. Starting with UDP
  49.  
  50.      To begin working with TCP, you must start before your client ever logs
  51. into the ICQ server.  At the same time as the UDP socket is created, you
  52. need to also create a listen()ing TCP socket and obtain its IP and port for
  53. sending with the initial login packet sent via UDP.  Your initial IP can be
  54. obtained by using gethostname() and then gethostbyname().  The PC ICQ
  55. clients always provide the client's LAN IP in favor of any ISP provided IP.
  56. Also be sure to set the client to client flag to 0x04 in the login packet
  57. so that other clients will know that your client is TCP capable.
  58.  
  59.      ULONG TCP_MsgPort; /* Port your client will accept TCP connections on. */
  60.      UWORD PassLength;  /* Length of password text. */
  61.      char  Password[];  /* Password, max 8 characters, case sensitive. */
  62.      ULONG X1;          /* Unknown.  Use 0x00000000 for v2. */
  63.      ULONG TCP_MsgIP;   /* IP Address your client will accept TCP connections on. */
  64.      UBYTE TCP_Flag;    /* Is your client TCP capable?  0x04 = Yes, 0x06 = No. */
  65.      ULONG Status;      /* Your client's status at login.  See defines. */
  66.      ULONG TCP_Ver;     /* The version of the TCP protocol used by the client. */
  67.      UWORD Seq_Login;   /* One up for each login packet sent. */
  68.      ULONG X4;          /* Unknown.  Use 0x00000000 for v2. */
  69.      ULONG X5;          /* Unknown.  For best results use 0x007300D9 with v2. */
  70.  
  71.      Before moving too far along, it must be noted that each type of
  72. connection creates its own listen()ing socket.  i.e. Message, Chat, and
  73. File connections will each have their own dedicated listener.  STRICQ
  74. follows the same convention as the PC client in that the Message socket is
  75. created at 'go online' time and the other two types are only created when
  76. that event occurs.  A chat listen socket is created only when someone
  77. requests a chat, the same for a file send/receive.
  78.  
  79.      Next we move to the S_USER_ONLINE (0x006E) packet.  The important
  80. information contained in this packet are the IP, Port, and TCP flag fields.
  81. The IP and Port are obviously necessary for making a direct TCP connection.
  82. The IP address is the IP that the ICQ server has extracted from the initial
  83. login UDP packet header NOT the IP in the login packet itself.  The Real IP
  84. is the IP provided by the client in the login packet, most often this is
  85. just a copy of the first IP, however, if the client found a LAN address,
  86. this will be the client's LAN IP.  Use the one byte TCP flag to determine
  87. whether a message packet should be sent via TCP or UDP.  If the flag is
  88. 0x04, attempt a TCP connect, otherwise send the message via UDP to the
  89. server for final delivery as an online message.  Usually, if the client is
  90. not TCP capable, then some kind of firewall/proxy is involved that blocks
  91. TCP connections.
  92.      
  93.      ULONG UIN;      /* The UIN of the user that is online. */
  94.      ULONG IP;       /* The IP address of the client (LAN External.) */
  95.      ULONG Port;     /* The Port to connect() with for sending messages. */
  96.      ULONG RealIP;   /* The actual IP of the client machine (LAN Internal.) */
  97.      UBYTE TCP_Flag; /* TCP Flag, 0x04 = TCP Capable, 0x06 = Do not use TCP. */
  98.      ULONG Status;   /* The status of the user at login. */
  99.      ULONG TCP_Ver;  /* The version of the TCP protocol used by the client. */
  100.  
  101.  
  102.                              3. Switch to TCP
  103.  
  104.      Once the user has entered a message to be sent to another person and
  105. the client determines the receiver is TCP capable and this is the first
  106. message sent to the receiver, a TCP connection is to be initiated.  The
  107. first order of business is to use the IP:Port from the online packet and
  108. attempt a connect().
  109.  
  110.  
  111.                           4. The TCP Init Packet
  112.  
  113.      After a successful connect(), the TCP Init packet is sent that sends
  114. some needed information and basically just says, "Hello."  Since we are
  115. assuming it is our client sending the first message and performed the
  116. connect(), it falls upon our end to start the ball rolling.  The following
  117. packet is a general TCP Init packet and is sent for ALL types of sockets,
  118. Message, Chat, and File.
  119.  
  120.      UBYTE Ident;       /* Always 0xFF. */
  121.      UWORD Version;     /* Version of the TCP protocol used. */
  122.      UWORD Revision;    /* Revision of the TCP protocol version (Mac clients.) */
  123.      ULONG TCP_ChatFilePort; /* Port of the client's chat/port listen() socket.  This
  124.                         /* is sent only for chat/file connects, otherwise NULL. */
  125.      ULONG UIN;         /* User's UIN. */
  126.      ULONG TCP_MsgIP;   /* IP address (LAN External.) */
  127.      ULONG TCP_RealIP;  /* IP address (LAN Internal.) */
  128.      UBYTE TCP_Flag;    /* TCP capable flag again, 0x04 = Yes, 0x06 = No. */
  129.      ULONG TCP_MsgPort; /* Port of the client's message listen() socket. This is
  130.                         /* sent ONLY for message connects, otherwise NULL. */
  131.  
  132.      After any TCP packet is built, the length of the packet is sent first
  133. followed by a second send() of the packet itself.  The easiest way to read
  134. this from the socket is to first read with a two-byte buffer, then perform
  135. a second read with a buffer size equal to the value retrieved in the first
  136. read.  Don't forget that TCP is 'sizeless', you could only receive half of
  137. your packet, or more than one packet at one time, this is why sending the
  138. actual packet size first is so important.  I leave it as an exercise of the
  139. reader how best to read the packets from the socket.
  140.  
  141.  
  142.                          5. The TCP Message Packet
  143.  
  144.      No reply will be sent from the remote end to a TCP Init packet.  Now,
  145. assuming we are sending a simple message, the following message packet is
  146. sent containing the actual message typed by our user.
  147.  
  148.      ULONG UIN;          /* Local UIN. */
  149.      UWORD Version;      /* TCP protocol version being used. */
  150.      UWORD Command;      /* Command.  Always 0x07EE.  See #DEFINEs. */
  151.      UWORD X1;           /* Always 0x0000. */
  152.      ULONG UIN;          /* Local UIN.  Just in case you missed it the first time. */
  153.      UWORD Type;         /* Message type.  See #DEFINEs. */
  154.      UWORD MsgLen;       /* Length of message.  Be prepared to accept any size. */
  155.      char  Message[];    /* The message text. */
  156.      ULONG TCP_MsgIP;    /* LAN External IP. */
  157.      ULONG TCP_RealIP;   /* LAN Internal IP. */
  158.      ULONG TCP_MsgPort;  /* Port of the current message socket. */
  159.      UBYTE TCP_Flag;     /* TCP Capable flag again. */
  160.      UWORD TCP_Status;   /* The client's status.  See #DEFINEs. */
  161.      UWORD MsgCommand;   /* Message command.  Usually 0x0010.  See #DEFINEs. */
  162.  
  163. For a Chat Request packet ONLY, also add the following:
  164.  
  165.      UWORD SessionLen;     /* Length of the Chat_Session text. */
  166.      char  Chat_Session[]; /* See the Chat Mode section for description. */
  167.      UWORD Chat_RevPort;   /* See the Chat Mode section for description. */
  168.      UWORD Chat_X2;        /* Always 0x0000, padding for port. */
  169.      ULONG Chat_Port;      /* See the Chat Mode section for description. */
  170.      
  171. For a FileDirect Request packet ONLY, also add the following:
  172.  
  173.      UWORD File_RevPort; /* Always 0x0000 in the message packet. */
  174.      UWORD File_X3;      /* Always 0x0000, padding for the port. */
  175.      UWORD FileNameLen;  /* Length of the filename text. */
  176.      char  File_Name[]   /* Name of the file being sent or a file count, '5 files,' if
  177.                          /* more than one file is being sent. */
  178.      ULONG File_Size;    /* The total size in bytes of all files being sent. */
  179.      ULONG File_Port;    /* Always 0x00000000 in the message packet. */
  180.  
  181. Finally, for all packets add the following:
  182.  
  183.      ULONG TCP_Sequence; /* The first TCP packet sent after program startup will have
  184.                          the sequence 0xFFFFFFFE.  The sequence is then decremented
  185.                          by one for EVERY TCP packet sent AND received regardless of
  186.                          who the sender or receiver is and does not include ACK
  187.                          packets. */
  188.  
  189.  
  190.                          6. The Message ACK Packet
  191.  
  192.      Once the remote client receives the TCP Message packet and the packet
  193. was correctly formatted, an ACK packet will be sent.  The PC client's
  194. message window will not go away and the little face window will continue to
  195. spin until this ACK packet is received back from the remote client.  The
  196. ACK packet is almost exactly the same as the received packet with several
  197. important changes.
  198.  
  199.      ULONG UIN;          /* Local UIN. */
  200.      UWORD Version;      /* TCP protocol version being used. */
  201.      UWORD Command;      /* Commands.  Always 0x07DA.  See #DEFINEs. */
  202.      UWORD X1;           /* Always 0x0000. */
  203.      ULONG UIN;          /* Local UIN.  Just in case you missed it the first time. */
  204.      UWORD Type;         /* Message type being ACK'd.  See #DEFINEs. */
  205.      UWORD MsgLen;       /* Length of auto-reply.  Be prepared to accept any size. */
  206.      char  Message[];    /* The auto-reply text. */
  207.      ULONG TCP_MsgIP;    /* LAN External IP. */
  208.      ULONG TCP_RealIP;   /* LAN Internal IP. */
  209.      ULONG TCP_MsgPort;  /* Port of the current message socket. */
  210.      UBYTE TCP_Flag;     /* TCP Capable flag again. */
  211.      UWORD TCP_Status;   /* The client's status.  See #DEFINEs. */
  212.      UWORD MsgCommand;   /* Message command.  Usually 0x0000.  See #DEFINEs. */
  213.  
  214. For a Chat Request ACK packet ONLY, also add the following:
  215.  
  216.      UWORD SessionLen;     /* Length of the Chat_Session text. */
  217.      char  Chat_Session[]; /* See the Chat Mode section for description. */
  218.      UWORD Chat_RevPort;   /* See the Chat Mode section for description. */
  219.      UWORD Chat_X2;        /* Always 0x0000, padding for port. */
  220.      ULONG Chat_Port;      /* See the Chat Mode section for description. */
  221.      
  222. For a FileDirect Request ACK packet ONLY, also add the following:
  223.  
  224.      UWORD File_RevPort; /* Port of the FileDirect listen() socket in network order. */
  225.      UWORD File_X3;      /* Always 0x0000, padding for the port. */
  226.      UWORD FileNameLen;  /* Always 0x0001. */
  227.      char  File_Name[]   /* Always 0x00. */
  228.      ULONG File_Size;    /* Always 0x00000000. */
  229.      ULONG File_Port;    /* Port of the FileDirect listen() socket in intel order. */
  230.  
  231. Finally, for all packets add the following:
  232.  
  233.      ULONG TCP_Sequence; /* The TCP Sequence of the message being ACK'd. */
  234.  
  235. Here is a list of changes or items to copy while creating the ACK packet:
  236.  
  237. 1. The Message Command changes from 0x07EE to 0x07DA.
  238. 2. The Message Type is copied from the original message packet.
  239. 3. Any configured Auto-Reply will be sent with this packet.
  240. 4. The Message Command Type changes from 0x0010 to 0x0000.
  241. 5. If the receiver refuses the request (Chat or File) the TCP_Status field
  242.    will be set to 0x0001.
  243. 6. The File ports are sent as NULL in the original packet and actually
  244.    filled in to the ACK packet by the receiver.  For Chat port handling,
  245.    see the Chat Mode description.
  246. 7. The Filename of a file send packet is set to NULL for the ACK.
  247. 8. The Filesize of a file send packet is set to NULL for the ACK.
  248. 9. The TCP Message Sequence is copied from the original message packet.
  249.  
  250.  
  251.                   7. TCP Message Packet Related #DEFINEs
  252.  
  253. /* TCP Commands */
  254.  
  255. #define TCP_CANCEL                0x07D0    /* 2000 TCP cancel previous file/chat request */
  256. #define TCP_ACK                   0x07DA    /* 2010 TCP acknowledge message packet */
  257. #define TCP_MESSAGE               0x07EE    /* 2030 TCP message */
  258.  
  259. /* TCP Message Types */
  260.  
  261. #define MSG_MSG                   0x0001    /* 0001 Used to send a normal message */
  262. #define MSG_CHAT                  0x0002    /* 0002 Used to initiate a Chat session */
  263. #define MSG_FILE                  0x0003    /* 0003 Used to initiate a FileDirect session */
  264. #define MSG_URL                   0x0004    /* 0004 Used to send a URL message */
  265. #define MSG_REQ_AUTH              0x0006    /* 0006 Used to request authorization to add to contact list */
  266. #define MSG_DENY_AUTH             0x0007    /* 0007 Used to deny authorization to add to contact list */
  267. #define MSG_GIVE_AUTH             0x0008    /* 0008 Used to grant authorization to add to contact list */
  268. #define MSG_ADDED                 0x000C    /* 0012 Used to notify that your UIN was added to a contact list */
  269. #define MSG_WEB_PAGER             0x000D    /* 0013 Used to receive a web pager message from the white page */
  270. #define MSG_EMAIL_PAGER           0x000E    /* 0014 Used to receive an EMail message from UIN@pager.mirabilis.com */
  271. #define MSG_ADDUIN                0x0013    /* 0019 Used to send UINs from one client to another */
  272. #define MSG_GREETING              0x001A    /* 0026 Used to send a greeting card */
  273.  
  274. #define MSG_READAWAY              0x03E8    /* 1000 Used to retrieve a clients Away message */
  275. #define MSG_READOCCUPIED          0x03E9    /* 1001 Used to retrieve a clients Occupied message */
  276. #define MSG_READNA                0x03EA    /* 1002 Used to retrieve a clients Not Available msg */
  277. #define MSG_READDND               0x03EB    /* 1003 Used to retrieve a clients Do Not Disturb msg*/
  278. #define MSG_READFFC               0x03EC    /* 1004 Used to retrieve a clients Free For Chat msg */
  279.  
  280. #define MSGF_MASS             0x0800    /* 2048 This message was sent to more than one UIN.  This is a flag and is
  281.                                         OR'd with one of the above */
  282.  
  283. /* TCP Message Command Types */
  284.  
  285. #define TCP_MSG_AUTO         0x0000  /* TCP message ACK and Auto-Reply */
  286. #define TCP_MSG_REAL         0x0010  /* TCP message */
  287. #define TCP_MSG_LIST         0x0020  /* TCP message sent to the contact list */
  288. #define TCP_MSG_URGENT       0x0040  /* TCP message sent urgently */
  289. /* The following are flags and are OR'd with the above Command Types */
  290. #define TCP_MSGF_S_INVISIBLE 0x0080  /* The message sender is Invisible */
  291. #define TCP_MSGF_S_AWAY      0x0100  /* The message sender is Away */
  292. #define TCP_MSGF_S_OCCUPIED  0x0200  /* The message sender is Occupied */
  293. #define TCP_MSGF_S_NA        0x0800  /* The message sender is Not Available */
  294. #define TCP_MSGF_S_DND       0x1000  /* The message sender is Do Not Disturb */
  295.  
  296. /* TCP Message Status' */
  297.  
  298. #define TCP_STAT_ONLINE      0x0000
  299. #define TCP_STAT_REFUSE      0x0001
  300. #define TCP_STAT_AWAY        0x0004
  301. #define TCP_STAT_OCCUPIED    0x0009
  302. #define TCP_STAT_DND         0x000A
  303. #define TCP_STAT_NA          0x000E
  304.  
  305.  
  306.                  8. Other Forms of the TCP Message Packet
  307.  
  308.      The TCP Cancel packet is formatted just like a normal message, file,
  309. or chat packet.  It is sent if the user presses the cancel button after
  310. sending the message, file, or chat message and before the receiving end has
  311. sent an ACK packet.  A cancel packet will have all its fields set to NULL,
  312. no text or port information will be sent.  The Message Type will be the
  313. same as the original message and the Message Command Type will be 0x0010.
  314. Also, the TCP Message Sequence will be the same as the original message.
  315.  
  316.      The MSG_READxxx Message types are ONLY received when the local client
  317. is in that particular mode.  The Win95 client can only send one Message
  318. Type at a time depending upon the status of the client the message is being
  319. read from.  What this means is that if your local client is in AWAY status
  320. mode, you will ONLY receive a message type of 0x03E8.  Your client's
  321. response when receiving one of these packets is to merely grab the
  322. configured message and send it with the ACK.  The PC clients do NOT notify
  323. the user when one of these messages are received.
  324.  
  325.  
  326.                         9. Reverse TCP Connections
  327.  
  328.      Before going into Chat and File negotiation, one more very important
  329. aspect of TCP connection negotiation involves what I call the Reverse TCP
  330. connection.  This is a UDP packet containing IP and Port information that
  331. is sent when client A wants to connect to client B, but for some reason, be
  332. it a firewall or whatever, the connect() failed.  Here is the breakout of
  333. the Reverse TCP connect UDP packet as created by the sender.
  334.  
  335. #define TCP_REQUEST        0x015E
  336.  
  337.      UWORD UDP_Ver;    /* Always 0x0002, UDP Version. */
  338.      UWORD UDP_Cmd;    /* 0x015E TCP_REQUEST packet. */
  339.      UWORD UDP_Seq;    /* UDP packet Sequence. */
  340.      ULONG UIN;        /* Receiver's UIN. */
  341.      ULONG Remote_UIN; /* Remote UIN of requester. */
  342.      ULONG IP;         /* Remote client's LAN External IP. */
  343.      ULONG Port;       /* listen() Port in INTEL order to connect() with. */
  344.      UBYTE TCP_Flag;   /* Always 0x04.  TCP Capable flag again. */
  345.      ULONG Port2;      /* Another Port in INTEL order.  Not sure what this is for. */
  346.      ULONG Port3;      /* listen() Port in INTEL order to connect() with, again. */
  347.      UWORD TCP_Ver;    /* TCP Protocol version of sender. */
  348.  
  349. The receiver will receive the above packet with this additional data:
  350.  
  351.      ULONG X1;         /* Always 0x00000000.  Unknown. */
  352.      ULONG X2;         /* Always 0x00000000.  Unknown. */
  353.  
  354.      This is the packet that client A builds and sends to client B via the
  355. server using UDP.  Once client B receives this packet from the server it
  356. will have 2 ULONGs of 0x00000000 appended to the end of the packet making
  357. it 8 bytes larger than what the sender sent.  I have never seen anything
  358. other than all NULLs for these extra bytes at the receiver end.
  359.  
  360. Here is the logic flow:
  361.  
  362. 1. User A types in a message to send to user B.
  363.  
  364. 2. Client A attempts to connect() with client B and fails.
  365.  
  366. 3. Client A builds the TCP_REQUEST packet and sends to the server.
  367.  
  368. 4. Client B receives the TCP_REQUEST packet with client A's IP:Port.
  369.  
  370. 5. Client B attempts to connect() to client A and succeeds.
  371.  
  372. 6. Client B sends the TCP Init packet to client A.
  373.  
  374. 7. Client A sends the message typed by user A in step 1.
  375.  
  376. 8. User B reads the message.
  377.  
  378.      The client that performs a successful connect() (client B) sends the
  379. TCP Init packet.  After that, packet flow resumes as normal just as if
  380. client A had actually performed the connect().
  381.  
  382.      The flow is essentially the same for Chat and File connections with a
  383. few small changes.  In the above example, client B knows the Reverse TCP
  384. connect is for an incoming message because client B did not ACCEPT anything
  385. from client A.  This is different for Chat and File.  Like so:
  386.  
  387. 0. User A requests to chat (or send a file) with user B.
  388.  
  389. 1. User B accepts the request of user A and client B sends the necessary
  390.      IP:Port information along with the Message ACK packet back to client
  391.      A.
  392.  
  393. 2. Client A attempts a connect() to the supplied IP:Port and fails.
  394.  
  395. Steps 3-6 from above are the same at this point.
  396.  
  397. 7. Client A sends the first actual Chat or File Init packet to client B.
  398.  
  399. 8. Client B responds with the appropriate next packet.
  400.  
  401.   In this example, client B knows what to expect because the Chat or File
  402. Message packet has already arrived and been accepted by the user.
  403.  
  404.  
  405.                          10. File Direct Protocol
  406.  
  407.      After following the above described methods to negotiate, open, and
  408. send the TCP Init packet, there are only seven packet types associated with
  409. the File Direct Protocol.  The first byte of the packets ranges from 0x00
  410. to 0x06.  The client sending the file(s) starts with packet 0x00, the
  411. receiver replies with packet 0x01, sender sends 0x02, receiver sends 0x03.
  412. Packets 0x04 and 0x05 are special packets and can be sent by either client
  413. at ANY TIME during the transfer.  Packet 0x06 contains the actual 2048
  414. bytes of the file being sent.  If more than one file is to be sent, after
  415. each file is finished and more files remain, the sender will again send
  416. packet 0x02 and the receiver will reply with 0x03.  Here are the steps to
  417. send two files:
  418.  
  419. S = Sender, R = Receiver.
  420.  
  421. S:0x00
  422. R:0x01
  423. S:0x02
  424. R:0x03
  425. S:0x06 (As many times to transfer the file as needed.)
  426. S:0x02
  427. R:0x03
  428. S:0x06 (Again, as many times as necessary.)
  429. S:Close the file direct socket.
  430.  
  431.   Here are the packet break outs:
  432.  
  433. UBYTE   0x00 Packet.
  434. DWORD   0x00000000 X1 Unknown.
  435. DWORD   Total number of all files to be sent.
  436. DWORD   Total bytes of all files to be sent.
  437. DWORD   Sender's speed of transfer. 0x00 to 0x64 where 0x00 = PAUSE and 0x64 =
  438.         No packet delay.  Each count represents a .05 second delay where 0x63
  439.         is a .05 second delay, 0x62 is a .10 second delay, 0x61 is a .15
  440.         second delay, etc. before sending the next packet.
  441. WORD    Length of Nick plus NULL.
  442. STRING  Sender's Nick.
  443.  
  444. ---
  445.  
  446. UBYTE   0x01 Packet.
  447. DWORD   Receiver's speed.
  448. WORD    Length of Nick plus NULL.
  449. STRING  Receiver's Nick.
  450.  
  451. ---
  452.  
  453. UBYTE   0x02 Packet.
  454. UBYTE   0x00 X1 Unknown.
  455. WORD    Length of filename.
  456. STRING  Name of next file to be sent.
  457. WORD    Length of text.  Always 0x01.
  458. STRING  Text.  Unknown.  Always just the NULL.
  459. DWORD   Size of the next file to be sent.
  460. DWORD   0x00000000 X2 Unknown.
  461. DWORD   Sender's speed.  (Yes, again...)
  462.  
  463. ---
  464.  
  465. UBYTE   0x03 Packet.
  466. DWORD   Size of file on receiver's end.  Any number here other than
  467.         0x00000000 will cause the sender to skip the specified number of
  468.         bytes before sending the first packet.  Used to implement file
  469.         transfer resume.
  470. DWORD   0x00000000 X1 Unknown.
  471. DWORD   Receiver's speed.  (Yes, again...)
  472.  
  473. ---
  474.  
  475. UBYTE   0x04 Packet.
  476. DWORD   Possibly the current file number being transfered.  Upon receipt of
  477.         this packet the sender will stop sending the current file and
  478.         either start on the next file or close the socket.
  479.  
  480. ---
  481.  
  482. UBYTE   0x05 Packet.
  483. DWORD   Change speed.  Can be sent by either client at any time during a
  484.         file transfer.
  485.  
  486. ---
  487.  
  488. UBYTE   0x06 Packet.
  489. ...     From 1 to 2048 bytes of the file being transferred.  The client
  490.         should always send 2048 bytes of the file until the final packet.
  491.  
  492.  
  493.                           11. Chat Mode Protocol
  494.  
  495.      User to user chat mode or single-chat is much more complicated than
  496. anything else in the ICQ protocol.  Add in multi-chat and the whole process
  497. becomes down right convoluted.  It has taken this author several months to
  498. work out just how the whole framework of single-chat and multi-chat all
  499. meshed together.  After much study it finally became clear that the
  500. listen() port used was key to understanding the whole process.  It turns
  501. out that single-chat is actually a striped down multi-chat, not, as was
  502. originally thought, multi-chat being a special case of, or built on top of,
  503. single-chat.
  504.  
  505.      As stated, the listen() port is key as it controls who connects with
  506. whom and whether or not the chat mode is single or multi.  From here on
  507. out, a 'Chat Session' will refer two or more clients connected in such a
  508. way that the sent and received text from all members will be seen within a
  509. single window.  Each chat listen() port controls its own chat session.  In
  510. other words, each chat session will have exactly one chat listen() port no
  511. matter how many users are participating in the chat session.
  512.  
  513.      To initiate single-chat mode, a user requests another user to enter
  514. chat.  The requester's client will create a chat listen() port at this
  515. time, however, it will not be passed to the receiver in the message packet.
  516. (This is the listen() port used if someone else wants to join this
  517. session.)  Next, the receiver accepts and the receiver's client opens a new
  518. chat session listen() socket and passes its port in the message ACK back to
  519. the requester.  The requester's client then attempts a connect() on that
  520. port.  The connection is made, the initial setup packets are passed back
  521. and forth and single-chat mode is entered.
  522.      
  523. Here is the chat mode section of the message packet as sent by the
  524. requester:
  525.  
  526.      UWORD SessionLen;     /* Always 0x0001 for single-chat. */
  527.      char  Chat_Session[]; /* Always 0x00 for single-chat. */
  528.      UWORD Chat_RevPort;   /* Always 0x0000 in the message packet. */
  529.      UWORD Chat_X2;        /* Always 0x0000, padding for port. */
  530.      ULONG Chat_Port;      /* Always 0x0000 in the message packet. */
  531.  
  532. Here is the chat mode section of the message ACK packet:
  533.  
  534.      UWORD SessionLen;     /* Always 0x0001 in the ACK packet. */
  535.      char  Chat_Session[]; /* Always 0x00 in the ACK packet. */
  536.      UWORD Chat_RevPort;   /* The chat listen() port in network order. */
  537.      UWORD Chat_X2;        /* Always 0x0000, padding for port. */
  538.      ULONG Chat_Port;      /* The chat listen() port in intel order. */
  539.  
  540.      The first method to initiate multi-chat mode starts when a user that
  541. is already in single-chat session (as described above) requests another
  542. user to join the chat session that is already in progress.  The initial
  543. message packet will contain a comma separated list of all users already in
  544. the chat session, i.e. 'User1, User2, User3', and port of the listen()
  545. socket that was created when the requester's client first sent/received a
  546. chat request message packet.  Next, the receiver accepts and the receiver's
  547. client opens a chat listen() socket and its port is passed back in the ACK
  548. packet.  After sending the message ACK packet, the receiver then attempts a
  549. connect() on the port passed in the message packet.  The connection is made
  550. and the initial setup packets are passed back and forth.  In these setup
  551. packets, the requester's client will pass some information on the other
  552. clients in the chat session.  This information allows the receiver's client
  553. to attempt connect()s with those other users in the chat session.  Once all
  554. the connections are made and the setup packets are passed between the
  555. receiver's client and the other members of the chat session, a multi-chat
  556. session is established between all users.
  557. Here is the chat mode section of the message packet as sent by the
  558. requester:
  559.  
  560.      UWORD SessionLen;     /* Length of the Chat_Session text. */
  561.      char  Chat_Session[]; /* Comma separated list of all those in the session. */
  562.      UWORD Chat_RevPort;   /* Chat listen() port for this session in network order. */
  563.      UWORD Chat_X2;        /* Always 0x0000, padding for port. */
  564.      ULONG Chat_Port;      /* Chat listen() port for this session in intel order. */
  565.  
  566. Here is the chat mode section of the message ACK packet:
  567.  
  568.      UWORD SessionLen;     /* Always 0x0001 in the ACK packet. */
  569.      char  Chat_Session[]; /* Always 0x00 in the ACK packet. */
  570.      UWORD Chat_RevPort;   /* Chat listen() port for this session in network order. */
  571.      UWORD Chat_X2;        /* Always 0x0000, padding for port. */
  572.      ULONG Chat_Port;      /* Chat listen() port for this session in intel order. */
  573.  
  574.      The next method used to enter into multi-chat is when a user requests
  575. to chat with a receiver that is already in a chat session.  In this
  576. instance, the chat portion of the message packet will be used in the exact
  577. same manner as if initiating a normal single-chat session.  The requesting
  578. client does not know or care that the receiver is already participating in
  579. a chat session.  Once the receiver receives the chat request, the user
  580. selects the join option and chooses a chat session already in progress.  At
  581. this point, instead of the receiving client making a new chat listen()
  582. socket, it passes the port of the chat listen() socket previously created
  583. when the first chat session was initiated.  (Now, if the receiving user had
  584. NOT chosen the join option, a new listen() socket would be created and a
  585. single-chat session would result with the receiver having two chat windows
  586. open at once.)  When the requesting client receives the ACK packet, it
  587. attempts a connect() on that port.  After the connect succeeds, the chat
  588. initialization packets are passed back and forth.  At this point the
  589. requesting client learns of the other clients also in the chat session and
  590. attempts to connect() with each of the other clients.  After all this a
  591. multi-chat session is in progress.
  592.  
  593.      Finally, the last case is where both the requester and receiver are
  594. both in a chat session already.  The PC ICQ clients do not allow for the
  595. 'merging' of two already in progress chat sessions.  If the requesting user
  596. selects the Join option, the receiver will not be given the Join option,
  597. and if the requester does not select Join, then the receiver is allowed the
  598. Join option.  Then one of the above three cases will be the resulting
  599. method used to initiate a chat session.
  600.  
  601.      Here are the chat initialization packets in detail.  There are three
  602. packets passed during the initialization phase.  The client that performed
  603. the connect() will send the first packet (with the exception of when a
  604. Reverse TCP Connect is used as stated above.)  The receiver will respond
  605. with the second packet, and the requester sends the third and final packet.
  606. At this point the socket becomes a character stream.  That portion of the
  607. chat mode will be described later.
  608.      
  609. First chat packet:
  610.  
  611.      ULONG HandShake;  /* Always 0x00000064.  ICQ99b uses 0x00000065. */
  612.      ULONG HiVersion;  /* Negative of the TCP protocol version.  V2 = 0xFFFFFFFE */
  613.      ULONG UIN;        /* Local UIN. */
  614.      UWORD NickLen;    /* Length of the nick. */
  615.      char  Nick[];     /* Local nick. */
  616.      UWORD RevPort;    /* Chat session port in network order. */
  617.      ULONG TextColor;  /* Text or font color in the form 0x00RRGGBB. */
  618.      ULONG BackColor;  /* Chat window background color in 0x00RRGGBB form. */
  619.      UBYTE X1;         /* Always 0x00. */
  620.  
  621. Second chat packet:
  622.  
  623.      ULONG HandShake;  /* Always 0x00000064.  ICQ99b uses 0x00000065. */
  624.      ULONG UIN;        /* Local UIN. */
  625.      UWORD NickLen;    /* Length of the nick. */
  626.      char  Nick[]; ;   /* Local nick. */
  627.      ULONG TextColor;  /* Text or font color in 0x00RRGGBB form. */
  628.      ULONG BackColor;  /* Background color in 0x00RRGGBB form. */
  629.      UWORD Version;    /* Version of TCP protocol used by the client. */
  630.      UWORD X1;         /* Revision of the TCP protocol, used by Mac clients. */
  631.      ULONG Port;       /* Chat session port in intel order. */
  632.      ULONG IP;         /* LAN External. */
  633.      ULONG RealIP;     /* LAN Internal. */
  634.      UBYTE TCP_Flag;   /* TCP capable flag again. */
  635.      UWORD X2;         /* Random, unique chat session identifier, use unknown. */
  636.      ULONG FontSize;   /* Size of the font. */
  637.      ULONG FontFamily; /* Font family?  Used for font substitution? */
  638.      UWORD FontLen;    /* Length of font name text. */
  639.      char  FontName[]; /* Font name. */
  640.      UWORD X3;         /* Usually 0x0002.  Unknown. */
  641.      UBYTE Count;      /* For single-chat, always 0x00.  When entering a chat session
  642.                           already in progress, this is a count of all other clients in
  643.                           the chat session. */
  644.  
  645. For single chat mode, this packet ends here with a Count of 0x00.  When
  646. entering a chat session already in progress, Count will be greater than
  647. 0x00.  For each other client in the chat session the following data will be
  648. appended to the second chat packet:
  649.  
  650.      UWORD Version;   /* Version of the TCP protocol used by the client. */
  651.      UWORD X1;        /* Revision of the TCP protocol, used by Mac clients. */
  652.      ULONG Port;      /* Chat session port in intel order. */
  653.      ULONG UIN;       /* UIN of the client being referenced. */
  654.      ULONG IP;        /* LAN External. */
  655.      ULONG RealIP;    /* LAN Internal. */
  656.      UWORD RevPort;   /* Chat session port in network order. */
  657.      UBYTE TCP_Flag;  /* TCP Capable flag. */
  658.      UWORD X2;        /* Random, unique chat session identifier, use unknown. */
  659.      ULONG HandShake; /* Always 0x00000064.  ICQ99b uses 0x00000065. */
  660.      
  661. It should be stated that the above additional data added to the second chat
  662. packet will be data that was stored during a previous chat initialization
  663. phase and has nothing to do with the client currently being connected to.
  664. Upon receipt of this additional data, the client will attempt to connect()
  665. with the supplied IP and port.  At this point a normal chat initialization
  666. phase will begin with each of these additional clients.  Also, each of
  667. these clients will send an extended second packet containing the data of
  668. all the other clients in the current session.  Be prepared to ignore the
  669. UINs of those clients in which a connection has already been established.
  670.  
  671. Third chat packet:
  672.  
  673.      UWORD Version;    /* Version of the TCP protocol used by the client. */
  674.      UWORD X1;         /* Revision of the TCP protocol, used by Mac clients. */
  675.      ULONG Port;       /* Chat listen() port in intel order. */
  676.      ULONG IP;         /* LAN External IP. */
  677.      ULONG RealIP;     /* LAN Internal IP. */
  678.      UBYTE TCP_Flag;   /* TCP Capable flag again. */
  679.      UWORD X2;         /* Random, unique chat session identifier, use unknown. */
  680.      ULONG FontSize;   /* Size of the font. */
  681.      ULONG FontFamily; /* Font family?  Used for font substitution? */
  682.      UWORD FontLen;    /* Length of font name. */
  683.      char  FontName[]; /* Font name. */
  684.      UWORD X3;         /* Usually 0x0002.  Unknown. */
  685.  
  686.      It is unknown what the random number is in the chat packets.  However,
  687. the PC ICQ clients will only make one number for each chat session.  If
  688. another, separate, chat session is started, then a new random number will
  689. be generated.
  690.  
  691.  
  692. To be continued...
  693.