home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 13 / AACD13.ISO / AACD / Online / StrICQ / Src / ICQ.c < prev    next >
C/C++ Source or Header  |  2000-02-16  |  37KB  |  1,625 lines

  1. /*
  2.  
  3. STRICQ - An Amiga, MUI Based, ICQ Clone.
  4. Copyright (C) 1998-2000 Douglas F. McLaughlin
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20. Douglas F. McLaughlin - stricq@owlnet.net
  21.  
  22. */
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <time.h>
  28.  
  29. #include <exec/memory.h>
  30. #include <exec/types.h>
  31.  
  32. #include <libraries/icq.h>
  33.  
  34. #include <proto/dos.h>
  35. #include <proto/exec.h>
  36.  
  37. #include "STRICQMUI.h"
  38.  
  39.  
  40. #define BCOPY_L(b)   L = BREV_L(b); memcpy(Buf+Len,&L,4); Len += 4
  41. #define BCOPY_W(b)   W = BREV_W(b); memcpy(Buf+Len,&W,2); Len += 2
  42. #define BCOPY_B(b)   memcpy(Buf+Len,&b,1); Len++
  43. #define BCOPY_S(s)   S = strlen(s)+1; BCOPY_W(S); strcpy(Buf+Len,(s)); Len += S
  44. #define BCOPY_M(b,l) memcpy(Buf+Len,(b),(l)); Len += (l);
  45.  
  46. #define ACOPY_L(b)   memcpy(&L,Buf+Len,4); b = BREV_L(L); Len += 4
  47. #define ACOPY_W(b)   memcpy(&W,Buf+Len,2); b = BREV_W(W); Len += 2
  48. #define ACOPY_B(b)   memcpy(&b,Buf+Len,1); Len++
  49. #define ACOPY_S(s)   ACOPY_W(S); strcpy((s),Buf+Len); Len += S
  50. #define ACOPY_P(s)   ACOPY_W(S); (s) = Buf+Len; Len += S
  51.  
  52. #define FCOPY_L(b)   memcpy(Buf+Len,&b,4); Len += 4;
  53. #define FCOPY_W(b)   memcpy(Buf+Len,&b,2); Len += 2;
  54.  
  55. #define ECOPY_L(b)   memcpy(&b,Buf+Len,4); Len += 4;
  56. #define ECOPY_W(b)   memcpy(&b,Buf+Len,2); Len += 2;
  57.  
  58. void  MSG_ParseMessage(UWORD, UBYTE *, APTR);
  59.  
  60. UWORD TCP_ParseTCPInit(struct TCP_Init *, UBYTE *);
  61.  
  62. UWORD TCP_CreateMsgPacket(struct TCP_Message *, UBYTE **, ULONG *, UWORD *);
  63. void  TCP_FreeMsgPacket(UBYTE *Buf);
  64. void  TCP_ParseMsgPacket(struct TCP_Message *, UBYTE *, ULONG *);
  65.  
  66. UWORD TCP_CreateFilePacket(UBYTE, APTR, UBYTE *, UWORD *);
  67.  
  68. UWORD TCP_CreateChatPacket(UBYTE, APTR, UBYTE *, UWORD *);
  69. UBYTE TCP_ParseChatPacket(void **, UBYTE *);
  70. UWORD TCP_CreateChatCmd(UBYTE, APTR, UBYTE *);
  71.  
  72. UWORD UDP_CreateHeader(struct UDP_Header *, UBYTE *);
  73. void  UDP_ParseHeader(UBYTE *, struct UDP_Header *);
  74. UWORD UDP_CreatePacket(struct UDP_Header *, APTR, UBYTE *);
  75. BOOL  UDP_EncryptPacket(UBYTE *, UBYTE *, UWORD);
  76. void  UDP_ParsePacket(APTR, UBYTE *, UWORD, struct UDP_Header *);
  77. void  UDP_ParseMeta(APTR, struct S_Meta *);
  78.  
  79. void  UDP_NextMulti(struct S_Multi *);
  80.  
  81. char *ICQ_CmdToText(UWORD);
  82.  
  83. ULONG CalcCheckCode(UBYTE *Buf, UWORD Len);
  84. ULONG ScrambleCheckCode(ULONG CheckCode);
  85. void  PrintHex(UBYTE, char *, UBYTE *, UWORD);
  86.  
  87. extern void HandleError(UBYTE, char *, ...);
  88.  
  89.  
  90. /*
  91. ** The following data constitutes fair use for compatibility.
  92. */
  93.  
  94. UBYTE UDP_Table[] = {
  95.  0x59, 0x60, 0x37 , 0x6B , 0x65 , 0x62 , 0x46 , 0x48 , 0x53 , 0x61 , 0x4C , 0x59 , 0x60 , 0x57 , 0x5B , 0x3D,
  96.  0x5E, 0x34, 0x6D , 0x36 , 0x50 , 0x3F , 0x6F , 0x67 , 0x53 , 0x61 , 0x4C , 0x59 , 0x40 , 0x47 , 0x63 , 0x39,
  97.  0x50, 0x5F, 0x5F , 0x3F , 0x6F , 0x47 , 0x43 , 0x69 , 0x48 , 0x33 , 0x31 , 0x64 , 0x35 , 0x5A , 0x4A , 0x42,
  98.  0x56, 0x40, 0x67 , 0x53 , 0x41 , 0x07 , 0x6C , 0x49 , 0x58 , 0x3B , 0x4D , 0x46 , 0x68 , 0x43 , 0x69 , 0x48,
  99.  0x33, 0x31, 0x44 , 0x65 , 0x62 , 0x46 , 0x48 , 0x53 , 0x41 , 0x07 , 0x6C , 0x69 , 0x48 , 0x33 , 0x51 , 0x54,
  100.  0x5D, 0x4E, 0x6C , 0x49 , 0x38 , 0x4B , 0x55 , 0x4A , 0x62 , 0x46 , 0x48 , 0x33 , 0x51 , 0x34 , 0x6D , 0x36,
  101.  0x50, 0x5F, 0x5F , 0x5F , 0x3F , 0x6F , 0x47 , 0x63 , 0x59 , 0x40 , 0x67 , 0x33 , 0x31 , 0x64 , 0x35 , 0x5A,
  102.  0x6A, 0x52, 0x6E , 0x3C , 0x51 , 0x34 , 0x6D , 0x36 , 0x50 , 0x5F , 0x5F , 0x3F , 0x4F , 0x37 , 0x4B , 0x35,
  103.  0x5A, 0x4A, 0x62 , 0x66 , 0x58 , 0x3B , 0x4D , 0x66 , 0x58 , 0x5B , 0x5D , 0x4E , 0x6C , 0x49 , 0x58 , 0x3B,
  104.  0x4D, 0x66, 0x58 , 0x3B , 0x4D , 0x46 , 0x48 , 0x53 , 0x61 , 0x4C , 0x59 , 0x40 , 0x67 , 0x33 , 0x31 , 0x64,
  105.  0x55, 0x6A, 0x32 , 0x3E , 0x44 , 0x45 , 0x52 , 0x6E , 0x3C , 0x31 , 0x64 , 0x55 , 0x6A , 0x52 , 0x4E , 0x6C,
  106.  0x69, 0x48, 0x53 , 0x61 , 0x4C , 0x39 , 0x30 , 0x6F , 0x47 , 0x63 , 0x59 , 0x60 , 0x57 , 0x5B , 0x3D , 0x3E,
  107.  0x64, 0x35, 0x3A , 0x3A , 0x5A , 0x6A , 0x52 , 0x4E , 0x6C , 0x69 , 0x48 , 0x53 , 0x61 , 0x6C , 0x49 , 0x58,
  108.  0x3B, 0x4D, 0x46 , 0x68 , 0x63 , 0x39 , 0x50 , 0x5F , 0x5F , 0x3F , 0x6F , 0x67 , 0x53 , 0x41 , 0x25 , 0x41,
  109.  0x3C, 0x51, 0x54 , 0x3D , 0x5E , 0x54 , 0x5D , 0x4E , 0x4C , 0x39 , 0x50 , 0x5F , 0x5F , 0x5F , 0x3F , 0x6F,
  110.  0x47, 0x43, 0x69 , 0x48 , 0x33 , 0x51 , 0x54 , 0x5D , 0x6E , 0x3C , 0x31 , 0x64 , 0x35 , 0x5A , 0x00 , 0x00,
  111. };
  112.  
  113. char version_icq[] = "$VER: icq.c 0.36 (06.12.99)\n\nCopyright © 1998-2000 Douglas F. McLaughlin\nICQ Protocol Copyright © 1996 Mirabilis LTD.\n\nAll Rights Reserved.";
  114. extern char err_buf[];
  115.  
  116. UBYTE TCP_Flag = TCP_FLAG_CAPABLE;
  117.  
  118. ULONG L, TCP_Sequence = 0xFFFFFFFE;
  119.  
  120. UWORD W, S, Len, Sequence, Sequence2, TCP_Version = TCP_VERSION_CURRENT;
  121.  
  122.  
  123. void MSG_ParseMessage(UWORD Type, UBYTE *Msg, APTR Data)
  124.  
  125. {
  126.  
  127. char *c, *d;
  128.  
  129. switch(Type) {
  130.   case MSG_MSG:
  131.   case MSG_CHAT:
  132.   case MSG_FILE:
  133.   case MSG_DENY_AUTH:
  134.   case MSG_GIVE_AUTH: {
  135.     struct MSG_Message *Message = Data;
  136.     Message->Message = Msg;
  137.     break;
  138.   }
  139.   case MSG_URL: {
  140.     struct MSG_URLDesc *URL = Data;
  141.     URL->Desc = c = Msg;
  142.     d = strchr(c,'\xFE');
  143.     *d = '\0';
  144.     URL->URL = d+1;
  145.     break;
  146.   }
  147.   case MSG_REQ_AUTH:
  148.   case MSG_ADDED:
  149.   case MSG_WEB_PAGER:
  150.   case MSG_EMAIL_PAGER: {
  151.     struct MSG_Common *Common = Data;
  152.     Common->Nick = c = Msg;
  153.     d = strchr(c,'\xFE');
  154.     *d = '\0';
  155.     Common->First = c = d+1;
  156.     d = strchr(c,'\xFE');
  157.     *d = '\0';
  158.     Common->Last = c = d+1;
  159.     d = strchr(c,'\xFE');
  160.     *d = '\0';
  161.     Common->EMail = c = d+1;
  162.     d = strchr(c,'\xFE');
  163.     *d = '\0';
  164.     Common->Authorize = (UBYTE)(*(d+1))&0x0F;
  165.     c = d+1;
  166.     d = strchr(c,'\xFE');
  167.     if (!d) Common->Message = c+1;
  168.     else Common->Message = d+1;
  169.     break;
  170.   }
  171.   case MSG_ADDUIN: {
  172.     struct MSG_AddUIN *AddUIN = Data;
  173.     c = Msg;
  174.     if (AddUIN->Total == 0) {
  175.       d = strchr(c,'\xFE');
  176.       *d = '\0';
  177.       StrToLong(c,(LONG *)&AddUIN->Total);
  178.       c = d+1;
  179.     }
  180.     d = strchr(c,'\xFE');
  181.     *d = '\0';
  182.     StrToLong(c,(LONG *)&AddUIN->UIN);
  183.     AddUIN->Nick = c = d+1;
  184.     d = strchr(c,'\xFE');
  185.     *d = '\0';
  186.     AddUIN->Next = d+1;
  187.     break;
  188.   }
  189. }
  190.  
  191. return;    
  192.  
  193. }
  194.  
  195.  
  196. UWORD TCP_ParseTCPInit(struct TCP_Init *Init, UBYTE *Buf)
  197.  
  198. {
  199.  
  200. UBYTE Ident;
  201.  
  202. UWORD PktLen;
  203.  
  204. Len = 0;
  205.  
  206. ACOPY_W(PktLen);
  207. ACOPY_B(Ident);
  208. ACOPY_W(Init->Version);
  209.  
  210. if (Ident != TCP_INIT_IDENT || Init->Version > TCP_VERSION_MAX) return(0);
  211.  
  212. ACOPY_W(Init->X1);                // This is probably a revision indicator...?
  213. ACOPY_L(Init->TCP_Chat_File_Port);
  214. ACOPY_L(Init->UIN);
  215. ECOPY_L(Init->TCP_MsgIP);
  216. ECOPY_L(Init->TCP_RealIP);
  217. ACOPY_B(Init->TCP_Flag);
  218. ACOPY_L(Init->TCP_MsgPort);
  219.  
  220. if (PktLen != Len-2) HandleError(DBG_TCP_ERRS,"TCP Init Packet passed with wrong size, received %d, expected %d",PktLen,Len-2);
  221.  
  222. return(PktLen);
  223.  
  224. }
  225.  
  226.  
  227. UWORD TCP_CreateMsgPacket(struct TCP_Message *TCPMsg, UBYTE **Buffer, ULONG *Sequence, UWORD *RevLen)
  228.  
  229. {
  230.  
  231. UBYTE *Buf;
  232.  
  233. ULONG pkt_size;
  234.  
  235. pkt_size = 4+2+2+2+4+2+2+strlen(TCPMsg->Message)+1+4+4+4+1+2+2+4;
  236.  
  237. switch(TCPMsg->Type) {
  238.   case MSG_CHAT:
  239.     pkt_size += 2+strlen(TCPMsg->Chat_Session)+1+2+2+4;
  240.     break;
  241.   case MSG_FILE:
  242.     pkt_size += 2+2+2+strlen(TCPMsg->File_Name)+1+4+4;
  243.     break;
  244. }
  245.  
  246. //HandleError(DBG_TCP_DBUG,"Created a TCP_Buf of %ld bytes.",pkt_size);
  247.  
  248. if (!(Buf = AllocVec(pkt_size,MEMF_CLEAR))) {
  249.   HandleError(DBG_OTH_FATL,"Out of memory creating a TCP Message packet.");
  250.   return(0);
  251. }
  252.  
  253. Len = 0;
  254.  
  255. BCOPY_L(TCPMsg->UIN);
  256. BCOPY_W(TCP_Version);
  257. BCOPY_W(TCPMsg->Command);
  258. BCOPY_W(TCPMsg->X1);
  259. BCOPY_L(TCPMsg->UIN);
  260. BCOPY_W(TCPMsg->Type);
  261. BCOPY_S(TCPMsg->Message);
  262. FCOPY_L(TCPMsg->TCP_MsgIP);
  263. FCOPY_L(TCPMsg->TCP_RealIP);
  264. BCOPY_L(TCPMsg->TCP_MsgPort);
  265. BCOPY_B(TCP_Flag);
  266. BCOPY_W(TCPMsg->TCP_Status);
  267. BCOPY_W(TCPMsg->MsgCommand);
  268.  
  269. switch(TCPMsg->Type) {
  270.   case MSG_CHAT:
  271.     BCOPY_S(TCPMsg->Chat_Session);
  272.     FCOPY_W(TCPMsg->Chat_RevPort);
  273.     BCOPY_W(TCPMsg->Chat_X2);
  274.     BCOPY_L(TCPMsg->Chat_Port);
  275.     break;
  276.   case MSG_FILE:
  277.     FCOPY_W(TCPMsg->File_RevPort);
  278.     BCOPY_W(TCPMsg->File_X3);
  279.     BCOPY_S(TCPMsg->File_Name);
  280.     BCOPY_L(TCPMsg->File_Size);
  281.     BCOPY_L(TCPMsg->File_Port);
  282.     break;
  283. }
  284.  
  285. BCOPY_L(TCP_Sequence);
  286.  
  287. PrintHex(DBG_TCP_PKTS,"TCP Message Packet",Buf,Len);
  288.  
  289. *Sequence = TCP_Sequence--;
  290.  
  291. *RevLen = BREV_W(Len);
  292.  
  293. *Buffer = Buf;
  294.  
  295. return(Len);
  296.  
  297. }
  298.  
  299.  
  300. void TCP_FreeMsgPacket(UBYTE *Buf)
  301.  
  302. {
  303.  
  304. FreeVec(Buf);
  305.  
  306. return;
  307.  
  308. }
  309.  
  310.  
  311. void TCP_ParseMsgPacket(struct TCP_Message *tcpmsg, UBYTE *Buf, ULONG *Sequence)
  312.  
  313. {
  314.  
  315. ULONG Seq = 0;
  316.  
  317. UWORD slen = 0;
  318.  
  319. Len = 0;
  320.  
  321. BCOPY_L(tcpmsg->UIN);
  322. BCOPY_W(tcpmsg->Command);
  323. BCOPY_W(tcpmsg->X1);
  324. BCOPY_W(tcpmsg->Type);
  325. BCOPY_W(slen);
  326. tcpmsg->Message = Buf+Len; Len += slen;
  327. FCOPY_L(tcpmsg->TCP_MsgIP);
  328. FCOPY_L(tcpmsg->TCP_RealIP);
  329. BCOPY_L(tcpmsg->TCP_MsgPort);
  330. BCOPY_W(tcpmsg->TCP_Status);
  331. BCOPY_W(tcpmsg->MsgCommand);
  332.  
  333. switch(tcpmsg->Type) {
  334.   case MSG_CHAT:
  335.     BCOPY_W(slen);
  336.     tcpmsg->Chat_Session = Buf+Len; Len += slen;
  337.     FCOPY_W(tcpmsg->Chat_RevPort);
  338.     BCOPY_W(tcpmsg->Chat_X2);
  339.     BCOPY_L(tcpmsg->Chat_Port);
  340.     break;
  341.   case MSG_FILE:
  342.     FCOPY_W(tcpmsg->File_RevPort);
  343.     BCOPY_W(tcpmsg->File_X3);
  344.     BCOPY_W(slen);
  345.     tcpmsg->File_Name = Buf+Len; Len += slen;
  346.     BCOPY_L(tcpmsg->File_Size);
  347.     BCOPY_L(tcpmsg->File_Port);
  348.     break;
  349. }
  350.  
  351. BCOPY_L(Seq);
  352.  
  353. *Sequence = Seq;
  354.  
  355. return;
  356.  
  357. }
  358.  
  359.  
  360. UWORD TCP_CreateFilePacket(UBYTE Cmd, APTR Data, UBYTE *Buf, UWORD *RevLen)
  361.  
  362. {
  363.  
  364. Len = 0;
  365.  
  366. switch(Cmd) {
  367.   case TCP_FILE_BEGIN: {
  368.     struct TCP_FileBegin *Begin = Data;
  369.     BCOPY_B(Cmd);
  370.     BCOPY_L(Begin->X1);
  371.     BCOPY_L(Begin->TotalFiles);
  372.     BCOPY_L(Begin->TotalSize);
  373.     BCOPY_L(Begin->Speed);
  374.     BCOPY_S(Begin->Nick);
  375.     break;
  376.   }
  377.   case TCP_FILE_READY: {
  378.     struct TCP_FileReady *Ready = Data;
  379.     BCOPY_B(Cmd);
  380.     BCOPY_B(Ready->X2);
  381.     BCOPY_S(Ready->Filename);
  382.     BCOPY_S(Ready->Text);
  383.     BCOPY_L(Ready->Filesize);
  384.     BCOPY_L(Ready->X2);
  385.     BCOPY_L(Ready->Speed);
  386.     break;
  387.   }
  388.   case TCP_FILE_SPEED: {
  389.     struct TCP_FileSpeed *Speed = Data;
  390.     BCOPY_B(Cmd);
  391.     BCOPY_L(Speed->Speed);
  392.     break;
  393.   }
  394.   case TCP_FILE_DATA: {
  395.     struct TCP_FileData *DataPkt = Data;
  396.     UWORD PktSize;
  397.     PktSize = DataPkt->DataLen + 1;
  398.     BCOPY_W(PktSize);
  399.     BCOPY_B(Cmd);
  400.     BCOPY_M(DataPkt->Data,DataPkt->DataLen);
  401.     Len -= 2;
  402.     break;
  403.   }
  404. }
  405.  
  406. *RevLen = BREV_W(Len);
  407.  
  408. if (Cmd != TCP_FILE_DATA) PrintHex(DBG_TCP_PKTS,"File Packet",Buf,(Cmd==TCP_FILE_DATA?32:Len));
  409.  
  410. return(Len);
  411.  
  412. }
  413.  
  414.  
  415. UWORD TCP_CreateChatPacket(UBYTE Cmd, APTR Data, UBYTE *Buf, UWORD *RevLen)
  416.  
  417. {
  418.  
  419. Len = 0;
  420.  
  421. switch(Cmd) {
  422.   case TCP_CHAT_1: {
  423.     struct TCP_ChatInit *Init = Data;
  424.     HandleError(DBG_TCP_DBUG,"Creating TCP_CHAT_1");
  425.     BCOPY_L(Init->HandShake);
  426.     BCOPY_L(Init->HiVersion);
  427.     BCOPY_L(Init->UIN);
  428.     BCOPY_S(Init->Nick);
  429.     FCOPY_W(Init->RevPort);
  430.     BCOPY_L(Init->TextColor);
  431.     BCOPY_L(Init->BackColor);
  432.     BCOPY_B(Init->X1);
  433.     break;
  434.   }
  435.   case TCP_CHAT_2: {
  436.     struct TCP_ChatTwo *Two = Data;
  437.     struct TCP_ChatTwo_Ext *ext_p1;
  438.     HandleError(DBG_TCP_DBUG,"Creating TCP_CHAT_2");
  439.     BCOPY_L(Two->HandShake);
  440.     BCOPY_L(Two->UIN);
  441.     BCOPY_S(Two->Nick);
  442.     BCOPY_L(Two->TextColor);
  443.     BCOPY_L(Two->BackColor);
  444.     BCOPY_W(Two->Version);
  445.     BCOPY_W(Two->X1);
  446.     BCOPY_L(Two->Port);
  447.     FCOPY_L(Two->IP);
  448.     FCOPY_L(Two->RealIP);
  449.     BCOPY_B(Two->TCP_Flag);
  450.     BCOPY_W(Two->X2);
  451.     BCOPY_L(Two->FontSize);
  452.     BCOPY_L(Two->FontFamily);
  453.     BCOPY_S(Two->FontName);
  454.     BCOPY_B(Two->X3);
  455.     BCOPY_B(Two->X4);
  456.     BCOPY_B(Two->Count);
  457.     ext_p1 = Two->Ext.Next;
  458.     while(ext_p1) {
  459.       BCOPY_W(ext_p1->Version);
  460.       BCOPY_W(ext_p1->X1);
  461.       BCOPY_L(ext_p1->Port);
  462.       BCOPY_L(ext_p1->UIN);
  463.       FCOPY_L(ext_p1->IP);
  464.       FCOPY_L(ext_p1->RealIP);
  465.       BCOPY_B(ext_p1->TCP_Flag);
  466.       BCOPY_W(ext_p1->RevPort);
  467.       BCOPY_W(ext_p1->X2);
  468.       BCOPY_L(ext_p1->HandShake);
  469.       ext_p1 = ext_p1->Next;
  470.     }
  471.     HandleError(DBG_TCP_DBUG,"TCP_CHAT_2");
  472.     break;
  473.   }
  474.   case TCP_CHAT_3: {
  475.     struct TCP_ChatThree *Three = Data;
  476.     HandleError(DBG_TCP_DBUG,"Creating TCP_CHAT_3");
  477.     BCOPY_W(Three->Version);
  478.     BCOPY_W(Three->X1);
  479.     BCOPY_L(Three->Port);
  480.     FCOPY_L(Three->IP);
  481.     FCOPY_L(Three->RealIP);
  482.     BCOPY_B(Three->TCP_Flag);
  483.     BCOPY_W(Three->X2);
  484.     BCOPY_L(Three->FontSize);
  485.     BCOPY_L(Three->FontFamily);
  486.     BCOPY_S(Three->FontName);
  487.     BCOPY_W(Three->X3);
  488.     break;
  489.   }
  490. }
  491.  
  492. *RevLen = BREV_W(Len);
  493.  
  494. PrintHex(DBG_TCP_PKTS,"Chat Initialization Packet",Buf,Len);
  495.  
  496. return(Len);
  497.  
  498. }
  499.  
  500.  
  501. UBYTE TCP_ParseChatPacket(void **Data, UBYTE *Buf)
  502.  
  503. {
  504.  
  505. UBYTE Cmd = TCP_CHAT_ERROR;
  506.  
  507. ULONG HandShake, HiVersion;
  508.  
  509. UWORD PktLen;
  510.  
  511. Len = 0;
  512.  
  513. ACOPY_W(PktLen);
  514. ACOPY_L(HandShake);
  515. ACOPY_L(HiVersion);
  516.  
  517. HandleError(DBG_TCP_DBUG,"HandShake %ld, HiVersion %ld",HandShake,HiVersion);
  518.  
  519. if (HandShake != TCP_CHAT_HANDSHAKE && HandShake != TCP_CHAT_HANDSHAKE2) Cmd = TCP_CHAT_3;
  520. else {
  521.   if (HiVersion >= TCP_CHAT_VERSION) Cmd = TCP_CHAT_1;
  522.   else Cmd = TCP_CHAT_2;
  523. }
  524.  
  525. Len = 0;
  526.  
  527. ACOPY_W(PktLen);
  528.  
  529. switch(Cmd) {
  530.   case TCP_CHAT_1: {
  531.     struct TCP_ChatInit *Init;
  532.     if (!(Init = (struct TCP_ChatInit *)AllocVec(sizeof(struct TCP_ChatInit),MEMF_CLEAR))) return(TCP_CHAT_ERROR);
  533.     ACOPY_L(Init->HandShake);
  534.     ACOPY_L(Init->HiVersion);
  535.     ACOPY_L(Init->UIN);
  536.     ACOPY_S(Init->Nick);
  537.     ECOPY_W(Init->RevPort);
  538.     ACOPY_L(Init->TextColor);
  539.     ACOPY_L(Init->BackColor);
  540.     ACOPY_B(Init->X1);
  541.     *Data = Init;
  542.     break;
  543.   }
  544.   case TCP_CHAT_2: {
  545.     struct TCP_ChatTwo *Two;
  546.     struct TCP_ChatTwo_Ext *ext_p1, *ext_p2;
  547.     if (!(Two = (struct TCP_ChatTwo *)AllocVec(sizeof(struct TCP_ChatTwo),MEMF_CLEAR))) return(TCP_CHAT_ERROR);
  548.     ACOPY_L(Two->HandShake);
  549.     ACOPY_L(Two->UIN);
  550.     ACOPY_S(Two->Nick);
  551.     ACOPY_L(Two->TextColor);
  552.     ACOPY_L(Two->BackColor);
  553.     ACOPY_W(Two->Version);
  554.     ACOPY_W(Two->X1);
  555.     ACOPY_L(Two->Port);
  556.     ECOPY_L(Two->IP);
  557.     ECOPY_L(Two->RealIP);
  558.     ACOPY_B(Two->TCP_Flag);
  559.     ACOPY_W(Two->X2);
  560.     ACOPY_L(Two->FontSize);
  561.     ACOPY_L(Two->FontFamily);
  562.     ACOPY_S(Two->FontName);
  563.     ACOPY_B(Two->X3);
  564.     ACOPY_B(Two->X4);
  565.     ACOPY_B(Two->Count);
  566.     ext_p2 = &Two->Ext;
  567.     ext_p2->Next = NULL;
  568.     while(PktLen > Len-2) {
  569.       if (!(ext_p1 = (struct TCP_ChatTwo_Ext *)AllocVec(sizeof(struct TCP_ChatTwo_Ext),MEMF_CLEAR))) break;
  570.       ext_p2->Next = ext_p1;
  571.       ext_p1->Next = NULL;
  572.       ACOPY_W(ext_p1->Version);
  573.       ACOPY_W(ext_p1->X1);
  574.       ACOPY_L(ext_p1->Port);
  575.       ACOPY_L(ext_p1->UIN);
  576.       ECOPY_L(ext_p1->IP);
  577.       ECOPY_L(ext_p1->RealIP);
  578.       ACOPY_B(ext_p1->TCP_Flag);
  579.       ACOPY_W(ext_p1->RevPort);
  580.       ACOPY_W(ext_p1->X2);
  581.       ACOPY_L(ext_p1->HandShake);
  582.       ext_p2 = ext_p1;
  583.     }
  584.     *Data = Two;
  585.     break;
  586.   }
  587.   case TCP_CHAT_3: {
  588.     struct TCP_ChatThree *Three;
  589.     if (!(Three = (struct TCP_ChatThree *)AllocVec(sizeof(struct TCP_ChatThree),MEMF_CLEAR))) return(TCP_CHAT_ERROR);
  590.     ACOPY_W(Three->Version);
  591.     ACOPY_W(Three->X1);
  592.     ACOPY_L(Three->Port);
  593.     ECOPY_L(Three->IP);
  594.     ECOPY_L(Three->RealIP);
  595.     ACOPY_B(Three->TCP_Flag);
  596.     ACOPY_W(Three->X2);
  597.     ACOPY_L(Three->FontSize);
  598.     ACOPY_L(Three->FontFamily);
  599.     ACOPY_S(Three->FontName);
  600.     ACOPY_W(Three->X3);
  601.     *Data = Three;
  602.     break;
  603.   }
  604. }
  605.  
  606. HandleError(DBG_TCP_DBUG,"Cmd is %d",Cmd);
  607.  
  608. return(Cmd);
  609.  
  610. }
  611.  
  612.  
  613. UWORD TCP_CreateChatCmd(UBYTE Cmd, APTR Data, UBYTE *Buf)
  614.  
  615. {
  616.  
  617. ULONG tmp;
  618.  
  619. Len = 0;
  620.  
  621. switch(Cmd) {
  622.   case TCP_CHAT_CMD_FCOLOR: {
  623.     struct TCP_ChatColor *Color = Data;
  624.     UBYTE Alpha = 0x00;
  625.     BCOPY_B(Cmd);
  626.     BCOPY_B(Color->Red);
  627.     BCOPY_B(Color->Green);
  628.     BCOPY_B(Color->Blue);
  629.     BCOPY_B(Alpha);
  630.     break;
  631.   }
  632.   case TCP_CHAT_CMD_STYLE: {
  633.     struct TCP_ChatCmdStyle *Style = Data;
  634.     BCOPY_B(Cmd);
  635.     tmp = (Style->Bold?TCP_CHATF_BOLD:TCP_CHATF_NONE) | (Style->Italic?TCP_CHATF_ITALIC:TCP_CHATF_NONE) | (Style->Underline?TCP_CHATF_UNDERLINE:TCP_CHATF_NONE);
  636.     BCOPY_L(tmp);
  637.     break;
  638.   }
  639. }
  640.  
  641. return(Len);
  642.  
  643. }
  644.  
  645.  
  646. UWORD UDP_CreatePacket(struct UDP_Header *Header, APTR Data, UBYTE *Buf)
  647.  
  648. {
  649.  
  650. if (Header->Command == C_LOGIN || Header->Command == C_NEW_USER_1) {
  651.   switch(Header->Version) {
  652.     case 0x0002:
  653.       Sequence = 0x0000;
  654.       break;
  655.     case 0x0005:
  656.       srand(time(NULL));
  657.       Header->SessionID = rand();
  658.       Sequence2 = rand() & 0x3FFF;
  659.       Sequence  = 0x0000;
  660.       Header->CheckCode = 0x00000000;
  661.       break;
  662.   }
  663. }
  664.  
  665. Len = UDP_CreateHeader(Header,Buf);
  666.  
  667. switch(Header->Command) {
  668.   case C_ACK: {
  669.     ULONG Random = rand();
  670.     switch(Header->Version) {
  671.     case 0x0005:
  672.       BCOPY_L(Random);
  673.       break;
  674.     }
  675.     break;
  676.   }
  677.   case C_SEND_MESSAGE: {
  678.     struct C_SendMessage *Msg = Data;
  679.     BCOPY_L(Msg->ToUIN);
  680.     BCOPY_W(Msg->Type);
  681.     BCOPY_S(Msg->Message);
  682.     break;
  683.   }
  684.   case C_LOGIN: {
  685.     struct C_LogOn *LogOn = Data;
  686.     switch(Header->Version) {
  687.       case 0x0005:
  688.         BCOPY_L(LogOn->Time);
  689.         break;
  690.     }
  691.     BCOPY_L(LogOn->TCP_MsgPort);
  692.     BCOPY_S(LogOn->Password);
  693.     BCOPY_L(LogOn->X1);
  694.     FCOPY_L(LogOn->TCP_MsgIP);
  695.     BCOPY_B(LogOn->TCP_Flag);
  696.     BCOPY_L(LogOn->Status);
  697.     BCOPY_L(LogOn->X3);
  698.     switch(Header->Version) {
  699.       case 0x0002:
  700.         BCOPY_W(LogOn->Seq_Login);
  701.         break;
  702.     }
  703.     BCOPY_L(LogOn->X4);
  704.     BCOPY_L(LogOn->X5);
  705.     switch(Header->Version) {
  706.       case 0x0005:
  707.         BCOPY_L(LogOn->X6);
  708.         BCOPY_L(LogOn->X7);
  709.         BCOPY_L(LogOn->X8);
  710.         break;
  711.     }
  712.     TCP_Flag = LogOn->TCP_Flag;
  713.     break;
  714.   }
  715.   case C_NEW_USER_REG: {
  716.     struct C_NewUser *NewUIN = Data;
  717.     switch(Header->Version) {
  718.       case 0x0002:
  719.         BCOPY_W(NewUIN->X1);
  720.         break;
  721.     }
  722.     BCOPY_S(NewUIN->Password);
  723.     BCOPY_L(NewUIN->X2);
  724.     BCOPY_W(NewUIN->Random);
  725.     BCOPY_W(NewUIN->Pad);
  726.     switch(Header->Version) {
  727.       case 0x0005:
  728.         BCOPY_L(NewUIN->X3);
  729.         BCOPY_L(NewUIN->X4);
  730.         break;
  731.     }
  732.     break;
  733.   }
  734.   case C_INVIS_LIST:
  735.   case C_VIS_LIST:
  736.   case C_CONTACT_LIST: {
  737.     int i;
  738.     struct C_ContactList *ContactList = Data;
  739.     BCOPY_B(ContactList->UIN_Count);
  740.     for(i = 0; i<ContactList->UIN_Count; i++) {
  741.       BCOPY_L(ContactList->UIN[i]);
  742.     }
  743.     break;
  744.   }
  745.   case C_SEARCH_USER: {
  746.     struct C_Search_User *Search = Data;
  747.     BCOPY_W(Search->Sequence);
  748.     BCOPY_S(Search->Nick);
  749.     BCOPY_S(Search->First);
  750.     BCOPY_S(Search->Last);
  751.     BCOPY_S(Search->EMail);
  752.     break;
  753.   }
  754.   case C_KEEP_ALIVE: {
  755.     ULONG Random = rand();
  756.     switch(Header->Version) {
  757.     case 0x0005:
  758.       BCOPY_L(Random);
  759.       break;
  760.     }
  761.     break;
  762.   }
  763.   case C_SEND_TEXT_CODE: {
  764.     struct C_LogOff *LogOff = Data;
  765.     BCOPY_S(LogOff->Text);
  766.     BCOPY_W(LogOff->X1);
  767.     break;
  768.   }
  769.   case C_ACK_MSG: {
  770.     ULONG Random = rand();
  771.     switch(Header->Version) {
  772.     case 0x0005:
  773.       BCOPY_L(Random);
  774.       break;
  775.     }
  776.     break;
  777.   }
  778.   case C_LOGIN_1: {
  779.     ULONG Random = rand();
  780.     switch(Header->Version) {
  781.     case 0x0005:
  782.       BCOPY_L(Random);
  783.       break;
  784.     }
  785.     break;
  786.   }
  787.   case C_INFO_REQ:
  788.   case C_EXT_INFO_REQ:{
  789.     struct C_Info_Req *Info = Data;
  790.     switch(Header->Version) {
  791.       case 0x0002:
  792.         BCOPY_W(Info->Sequence);
  793.         Info->Sequence++;
  794.         break;
  795.     }
  796.     BCOPY_L(Info->UIN);
  797.     break;
  798.   }
  799.   case C_CHANGE_PASSWORD: {
  800.     struct C_ChangePassword *Pass = Data;
  801.     switch(Header->Version) {
  802.       case 0x0002:
  803.         BCOPY_W(Pass->Sequence);
  804.         break;
  805.     }
  806.     BCOPY_S(Pass->Password);
  807.     break;
  808.   }
  809.   case C_UPDATE_INFO:
  810.   case C_NEW_USER_INFO: {
  811.     struct C_Update_Basic_Info *Basic = Data;
  812.     switch(Header->Version) {
  813.       case 0x0002:
  814.         BCOPY_W(Basic->Sequence);
  815.         break;
  816.     }
  817.     BCOPY_S(Basic->Nick);
  818.     BCOPY_S(Basic->First);
  819.     BCOPY_S(Basic->Last);
  820.     BCOPY_S(Basic->EMail);
  821.     BCOPY_B(Basic->Authorize);
  822.     break;
  823.   }
  824.   case C_UPDATE_EXT_INFO: {
  825.     struct C_Update_Ext_Info *Extended = Data;
  826.     switch(Header->Version) {
  827.       case 0x0002:
  828.         BCOPY_W(Extended->Sequence);
  829.         break;
  830.     }
  831.     BCOPY_S(Extended->City);
  832.     BCOPY_W(Extended->Country);
  833.     BCOPY_B(Extended->Timezone);
  834.     BCOPY_S(Extended->State);
  835.     BCOPY_W(Extended->Age);
  836.     BCOPY_B(Extended->Sex);
  837.     BCOPY_S(Extended->Phone);
  838.     BCOPY_S(Extended->URL);
  839.     BCOPY_S(Extended->About);
  840.     break;
  841.   }
  842.   case C_QUERY_STATUS: {
  843.     struct C_ServerStat *SrvrStat = Data;
  844.     BCOPY_L(SrvrStat->Index);
  845.     break;
  846.   }
  847.   case C_LOGIN_3: {
  848.     struct C_LogOn_3 *LogOn3 = Data;
  849.     BCOPY_L(LogOn3->X1);
  850.     break;
  851.   }
  852.   case C_STATUS_CHANGE: {
  853.     struct C_StatusChange *Status = Data;
  854.     BCOPY_L(Status->Status);
  855.     break;
  856.   }
  857.   case C_SEND_URL_MESSAGE: {
  858.     struct C_SendURLMsg *URLMsg = Data;
  859.     BCOPY_L(URLMsg->Index);
  860.     break;
  861.   }
  862.   case C_UPDATE_AUTH: {
  863.     struct C_UpdateAuth *Auth = Data;
  864.     BCOPY_W(Auth->Sequence);
  865.     BCOPY_B(Auth->Authorize);
  866.     break;
  867.   }
  868.   case C_LOGIN_2: {
  869.     struct C_LogOn_2 *LogOn2 = Data;
  870.     BCOPY_B(LogOn2->X1);
  871.     break;
  872.   }
  873.   case C_NEW_USER_1:
  874.     break;
  875.   case C_META: {
  876.     struct C_Meta *Meta = Data;
  877.     BCOPY_W(Meta->Subcommand);
  878.     BCOPY_L(Meta->UIN);
  879.     break;
  880.   }
  881. }
  882.  
  883. return(Len);
  884.  
  885. }
  886.  
  887.  
  888. BOOL UDP_EncryptPacket(UBYTE *Buf, UBYTE *OldBuf, UWORD Len)
  889.  
  890. {
  891.  
  892. ULONG code, data1, checkcode;
  893. UWORD pos;
  894.  
  895. if (Len < 0x19) {
  896.   HandleError(DBG_UDP_ERRS,"UDP_EncryptPacket() - Packet has no data!");
  897.   return(FALSE);
  898. }
  899.  
  900. memcpy(Buf,OldBuf,Len);
  901.  
  902. checkcode = CalcCheckCode(Buf,Len);
  903.  
  904. code = Len * 0x68656c6c + checkcode;
  905.  
  906. for(pos = 0x0a; pos < Len; pos += 4) {
  907.   memcpy(&L,Buf + pos,4); data1 = BREV_L(L);
  908.   data1 ^= code + UDP_Table[pos & 0xFF];
  909.   L = BREV_L(data1); memcpy(Buf + pos,&L,4);
  910. }
  911.  
  912. checkcode = ScrambleCheckCode(checkcode);
  913.  
  914. L = BREV_L(checkcode); memcpy(Buf + 0x14,&L,4);
  915.  
  916. return(TRUE);
  917.  
  918. }
  919.  
  920.  
  921. ULONG CalcCheckCode(UBYTE *Buf, UWORD Len)
  922.  
  923. {
  924.  
  925. ULONG Number1, Number2, CheckCode;
  926.  
  927. UBYTE r1, r2;
  928.  
  929. Number1 = Buf[8];
  930. Number1 <<= 8;
  931. Number1 += Buf[4];
  932. Number1 <<= 8;
  933. Number1 += Buf[2];
  934. Number1 <<= 8;
  935. Number1 += Buf[6];
  936.  
  937. r1 = (rand() % (Len - 0x18)) + 0x18;
  938. r2 = rand() & 0xFF;
  939.  
  940. Number2 = r1;
  941. Number2 <<= 8;
  942. Number2 += Buf[r1];
  943. Number2 <<= 8;
  944. Number2 += r2;
  945. Number2 <<= 8;
  946. Number2 += UDP_Table[r2];
  947. Number2 ^= 0xFF00FF;
  948.  
  949. CheckCode = Number1 ^ Number2;
  950.  
  951. //HandleError(DBG_UDP_DBUG,"n1 = %08lx, r1 = %02x, r2 = %02x, Buf[r1] = %02x, Table[r2] = %02x, n2 = %08lx, CheckCode = %08x",Number1,r1,r2,Buf[r1],UDP_Table[r2],Number2,CheckCode);
  952.  
  953. return(CheckCode);
  954.  
  955. }
  956.  
  957.  
  958. ULONG ScrambleCheckCode(ULONG CheckCode)
  959.  
  960. {
  961.  
  962. ULONG a[6];
  963.  
  964. a[1] = CheckCode & 0x0000001F;
  965. a[2] = CheckCode & 0x03E003E0;
  966. a[3] = CheckCode & 0xF8000400;
  967. a[4] = CheckCode & 0x0000F800;
  968. a[5] = CheckCode & 0x041F0000;
  969.  
  970. a[1] <<= 0x0C;
  971. a[2] <<= 0x01;
  972. a[3] >>= 0x0A;
  973. a[4] <<= 0x10;
  974. a[5] >>= 0x0F;
  975.  
  976. return(a[1] + a[2] + a[3] + a[4] + a[5]);
  977.  
  978. }
  979.  
  980.  
  981. void UDP_ParsePacket(APTR Data, UBYTE *Buf, UWORD PktLen, struct UDP_Header *Header)
  982.  
  983. {
  984.  
  985. switch(Header->Version) {
  986.   case 0x0002:
  987.     Len = 6;
  988.     break;
  989.   case 0x0005:
  990.     Len = 21;
  991.     break;
  992. }
  993.  
  994. switch(Header->Command) {
  995.   case S_ACK:
  996.     break;
  997.   case S_GO_AWAY:
  998.     PrintHex(DBG_UDP_ERRS,"S_GO_AWAY",Buf,PktLen);
  999.     break;
  1000.   case S_NEW_USER_UIN:
  1001.     switch(Header->Version) {
  1002.       case 0x0002: {
  1003.         struct S_New_User_UIN *NewUIN = Data;
  1004.         ACOPY_W(NewUIN->X1);
  1005.         ACOPY_L(NewUIN->UIN);
  1006.         ACOPY_L(NewUIN->Random);
  1007.         break;
  1008.       }
  1009.       case 0x0005:
  1010.         PrintHex(DBG_UDP_ERRS,"S_NEW_USER_UIN",Buf,PktLen);
  1011.         break;
  1012.     }
  1013.     break;
  1014.   case S_LOGIN_REPLY: {
  1015.     struct S_Login_Reply *Login = Data;
  1016.     switch(Header->Version) {
  1017.       case 0x0002:
  1018.         ECOPY_L(Login->IP);
  1019. //      ACOPY_W(Login->X1);
  1020. //      ACOPY_W(Login->X2);
  1021. //      ACOPY_W(Login->X3);
  1022. //      ACOPY_L(Login->X4);
  1023. //      ACOPY_L(Login->X5);
  1024. //      ACOPY_W(Login->X6);
  1025. //      ACOPY_W(Login->X7);
  1026. //      ACOPY_W(Login->X8);
  1027. //      ACOPY_W(Login->X9);
  1028. //      ACOPY_W(Login->X10);
  1029. //      ACOPY_W(Login->X11);
  1030. //      ACOPY_L(Login->X12);
  1031.         break;
  1032.       case 0x0005:
  1033.         ACOPY_L(Login->X5);
  1034.         ACOPY_W(Login->X6);
  1035.         ACOPY_W(Login->X7);
  1036.         ACOPY_W(Login->X8);
  1037.         ACOPY_W(Login->X9);
  1038.         ECOPY_L(Login->IP);
  1039. //      ACOPY_L(Login->X12);
  1040.         break;
  1041.     }
  1042.     break;
  1043.   }
  1044.   case S_BAD_PASSWORD:
  1045.     PrintHex(DBG_UDP_ERRS,"S_BAD_PASSWORD",Buf,PktLen);
  1046.     break;
  1047.   case S_USER_ONLINE: {
  1048.     struct S_User_Online *Online = Data;
  1049.     ACOPY_L(Online->UIN);
  1050.     ECOPY_L(Online->IP);
  1051.     ACOPY_L(Online->TCP_MsgPort);
  1052.     ECOPY_L(Online->RealIP);
  1053.     ACOPY_B(Online->TCP_Flag);
  1054.     ACOPY_L(Online->Status);
  1055.     ACOPY_W(Online->TCP_Version);
  1056.     ACOPY_W(Online->TCP_Revision);
  1057.     break;
  1058.   }
  1059.   case S_USER_OFFLINE: {
  1060.     struct S_User_Offline *Offline = Data;
  1061.     ACOPY_L(Offline->UIN);
  1062.     break;
  1063.   }
  1064.   case S_QUERY_REPLY:
  1065.     break;
  1066.   case S_USER_FOUND:
  1067.   case S_INFO_REPLY: {
  1068.     struct S_Basic_Info *Basic = Data;
  1069.     switch(Header->Version) {
  1070.       case 0x0002:
  1071.         ACOPY_W(Basic->Sequence);
  1072.         break;
  1073.     }
  1074.     ACOPY_L(Basic->UIN);
  1075.     ACOPY_S(Basic->Nick);
  1076.     ACOPY_S(Basic->First);
  1077.     ACOPY_S(Basic->Last);
  1078.     ACOPY_S(Basic->EMail);
  1079.     ACOPY_B(Basic->Authorize);
  1080.     break;
  1081.   }
  1082.   case S_END_OF_SEARCH: {
  1083.     struct S_End_Of_Search *Search = Data;
  1084.     switch(Header->Version) {
  1085.       case 0x0002:
  1086.         ACOPY_W(Search->Sequence);
  1087.         break;
  1088.     }
  1089.     ACOPY_B(Search->TooMany);
  1090.     break;
  1091.   }
  1092.   case S_NEW_USER_REPLY:
  1093.   case S_UPDATE_EXT_REPLY:
  1094.     break;
  1095.   case S_RECEIVE_MESSAGE: {
  1096.     struct S_Receive_Message *Msg = Data;
  1097.     ACOPY_L(Msg->UIN);
  1098.     ACOPY_W(Msg->Year);
  1099.     ACOPY_B(Msg->Month);
  1100.     ACOPY_B(Msg->Day);
  1101.     ACOPY_B(Msg->Hour);
  1102.     ACOPY_B(Msg->Minute);
  1103.     ACOPY_W(Msg->Type);
  1104.     ACOPY_W(Msg->Length);
  1105.     Msg->MessageBuf = Buf+Len;
  1106.     break;
  1107.   }
  1108.   case S_END_OFFLINE_MSGS:
  1109.   case S_TOO_BUSY:
  1110.     break;
  1111.   case S_GET_MESSAGE: {
  1112.     struct S_Get_Message *Msg = Data;
  1113.     ACOPY_L(Msg->UIN);
  1114.     ACOPY_W(Msg->Type);
  1115.     ACOPY_W(Msg->Length);
  1116.     Msg->MessageBuf = Buf+Len;
  1117.     break;
  1118.   }
  1119.   case S_EXT_INFO_REPLY: {
  1120.     struct S_Ext_Info *Ext = Data;
  1121.     switch(Header->Version) {
  1122.       case 0x0002:
  1123.         ACOPY_W(Ext->Sequence);
  1124.         break;
  1125.     }
  1126.     ACOPY_L(Ext->UIN);
  1127.     ACOPY_S(Ext->City);
  1128.     ACOPY_W(Ext->Country);
  1129.     ACOPY_B(Ext->Timezone);
  1130.     ACOPY_S(Ext->State);
  1131.     ACOPY_W(Ext->Age);
  1132.     ACOPY_B(Ext->Sex);
  1133.     ACOPY_S(Ext->Phone);
  1134.     ACOPY_S(Ext->URL);
  1135.     ACOPY_S(Ext->About);
  1136.     break;
  1137.   }
  1138.   case S_INFO_NOT_FOUND:
  1139.   case S_EXT_INFO_NOT_FOUND:
  1140.     break;
  1141.   case S_TCP_REQUEST: {
  1142.     struct S_TCP_Request *Req = Data;
  1143.     switch(Header->Version) {
  1144.       case 0x0002:
  1145.         ACOPY_L(Req->Local_UIN);
  1146.         break;
  1147.     }
  1148.     ACOPY_L(Req->Remote_UIN);
  1149.     ECOPY_L(Req->IP);
  1150.     ACOPY_L(Req->Port);
  1151.     ACOPY_B(Req->TCP_Flag);
  1152.     ACOPY_L(Req->Port2);
  1153.     ACOPY_L(Req->Port3);
  1154.     ACOPY_W(Req->TCP_Version);
  1155. //  ACOPY_L(Req->X1);
  1156. //  ACOPY_L(Req->X2);
  1157.     break;
  1158.   }
  1159.   case S_STATUS_UPDATE : {
  1160.     struct S_Status_Update *Status = Data;
  1161.     ACOPY_L(Status->UIN);
  1162.     ACOPY_L(Status->Status);
  1163.     break;
  1164.   }
  1165.   case S_SYSTEM_MESSAGE: {
  1166.     struct S_System_Message *Sys = Data;
  1167.     switch(Header->Version) {
  1168.       case 0x0002:
  1169.         ACOPY_L(Sys->Index);
  1170.         ACOPY_S(Sys->Ad);
  1171.         ACOPY_S(Sys->URL);
  1172.         ACOPY_S(Sys->Button);
  1173.         break;
  1174.       case 0x0005:
  1175.         PrintHex(DBG_UDP_ERRS,"S_SYSTEM_MESSAGE",Buf,PktLen);
  1176.         break;
  1177.     }
  1178.     break;
  1179.   }
  1180.   case S_UPDATE_REPLY:
  1181.   case S_UPDATE_FAIL:
  1182.   case S_UPDATE_AUTH_REPLY:
  1183.     break;
  1184.   case S_META: {
  1185.     struct S_Meta *Meta = Data;
  1186.     ACOPY_W(Meta->Subcommand);
  1187.     ACOPY_B(Meta->Success);
  1188.     Meta->Packet = Buf + Len;
  1189.     break;
  1190.   }
  1191.   case S_REPLY_X1:
  1192.     PrintHex(DBG_UDP_ERRS,"S_REPLY_X1",Buf,PktLen);
  1193.     break;
  1194.   case S_MULTI: {
  1195.     struct S_Multi *Multi = Data;
  1196.     ACOPY_B(Multi->Count);
  1197.     ACOPY_W(Multi->Size);
  1198.     Multi->Packet = Buf + Len;
  1199.     break;
  1200.   }
  1201. }
  1202.  
  1203. return;
  1204.  
  1205. }
  1206.  
  1207.  
  1208. void UDP_NextMulti(struct S_Multi *Multi)
  1209.  
  1210. {
  1211.  
  1212. UBYTE *Buf;
  1213.  
  1214. UWORD Len = 0;
  1215.  
  1216. if ((--Multi->Count) == 0) {
  1217.   Multi->Size = 0;
  1218.   Multi->Packet = NULL;
  1219.   return;
  1220. }
  1221.  
  1222. Buf = Multi->Packet + Multi->Size;
  1223.  
  1224. ACOPY_W(Multi->Size);
  1225.  
  1226. Multi->Packet = Buf + Len;
  1227.  
  1228. return;
  1229.  
  1230. }
  1231.  
  1232.  
  1233. void  UDP_ParseMeta(APTR Data, struct S_Meta *Meta)
  1234.  
  1235. {
  1236.  
  1237. UBYTE *Buf = Meta->Packet;
  1238.  
  1239. Len = 0;
  1240.  
  1241. switch(Meta->Subcommand) {
  1242.   case META_INFO_HOME: {
  1243.     struct Meta_Info_Home *Home = Data;
  1244.     ACOPY_S(Home->Nick);
  1245.     ACOPY_S(Home->First);
  1246.     ACOPY_S(Home->Last);
  1247.     ACOPY_S(Home->EMail_Primary);
  1248.     ACOPY_S(Home->EMail_Secondary);
  1249.     ACOPY_S(Home->EMail_Old);
  1250.     ACOPY_S(Home->City);
  1251.     ACOPY_S(Home->State);
  1252.     ACOPY_S(Home->Phone);
  1253.     ACOPY_S(Home->FAX);
  1254.     ACOPY_S(Home->Street);
  1255.     ACOPY_S(Home->Cellular);
  1256.     ACOPY_S(Home->ZipCode);
  1257.     ACOPY_W(Home->Country);
  1258.     ACOPY_B(Home->Timezone);
  1259.     ACOPY_B(Home->Flag1);
  1260.     ACOPY_B(Home->Flag2);    /* Depending on the circumstance, these last three flags may not actually */
  1261.     ACOPY_B(Home->Flag3);    /*   have been sent by the server.  No harm in always copying them as the */
  1262.     ACOPY_B(Home->Flag4);    /*   calling program should always know which flags were actually sent.   */
  1263.     break;
  1264.   }
  1265.   case META_INFO_WORK: {
  1266.     struct Meta_Info_Work *Work = Data;
  1267.     ACOPY_S(Work->City);
  1268.     ACOPY_S(Work->State);
  1269.     ACOPY_S(Work->Phone);
  1270.     ACOPY_S(Work->FAX);
  1271.     ACOPY_S(Work->Address);
  1272.     ACOPY_S(Work->ZipCode);
  1273.     ACOPY_W(Work->Country);
  1274.     ACOPY_S(Work->Company);
  1275.     ACOPY_S(Work->Department);
  1276.     ACOPY_S(Work->Position);
  1277.     ACOPY_W(Work->Occupation);
  1278.     ACOPY_S(Work->URL);
  1279.     break;
  1280.   }
  1281.   case META_INFO_MORE: {
  1282.     struct Meta_Info_More *More = Data;
  1283.     ACOPY_W(More->Age);
  1284.     ACOPY_B(More->Sex);
  1285.     ACOPY_S(More->URL);
  1286.     ACOPY_W(More->BDay_Year);
  1287.     ACOPY_B(More->BDay_Month);
  1288.     ACOPY_B(More->BDay_Day);
  1289.     ACOPY_B(More->Language1);
  1290.     ACOPY_B(More->Language2);
  1291.     ACOPY_B(More->Language3);
  1292.     break;
  1293.   }
  1294.   case META_INFO_ABOUT: {
  1295.     struct Meta_Info_About *About = Data;
  1296.     ACOPY_S(About->About);
  1297.     break;
  1298.   }
  1299.   case META_INFO_INTERESTS: {
  1300.     struct Meta_Info_Interests *Interest = Data;
  1301.     ACOPY_B(Interest->Total_Categories);
  1302.     ACOPY_W(Interest->Topic);
  1303.     ACOPY_P(Interest->TopicText);
  1304.     Interest->Next_Category = Buf + Len;
  1305.     break;
  1306.   }
  1307.   case META_INFO_AFFILIATIONS: {
  1308.     struct Meta_Info_Affiliations *Affiliation = Data;
  1309.     ACOPY_B(Affiliation->Total_Backgrounds);
  1310.     if (Affiliation->Total_Backgrounds) {
  1311.       ACOPY_W(Affiliation->Background);
  1312.       ACOPY_P(Affiliation->BackgroundText);
  1313.       Affiliation->Next_Background = Buf + Len;
  1314.       break;
  1315.     }
  1316.     ACOPY_B(Affiliation->Total_Affiliations);
  1317.     if (Affiliation->Total_Affiliations) {
  1318.       ACOPY_W(Affiliation->Affiliation);
  1319.       ACOPY_P(Affiliation->AffiliationText);
  1320.       Affiliation->Next_Affiliation = Buf + Len;
  1321.     }
  1322.     break;
  1323.   }
  1324.   case META_INFO_URLCATEGORY: {
  1325.     struct Meta_Info_URLCategory *URLCat = Data;
  1326.     ACOPY_B(URLCat->Total_Categories);
  1327.     ACOPY_W(URLCat->Category);
  1328.     ACOPY_P(URLCat->AboutText);
  1329.     URLCat->Next_Category = Buf + Len;
  1330.     break;
  1331.   }
  1332. }
  1333.  
  1334. return;
  1335.  
  1336. }
  1337.  
  1338.  
  1339. UWORD UDP_CreateHeader(struct UDP_Header *Header, UBYTE *Buf)
  1340.  
  1341. {
  1342.  
  1343. UWORD Zero = 0;
  1344.  
  1345. Len = 0;
  1346.  
  1347. switch(Header->Version) {
  1348.   case 0x0002:
  1349.     if (Header->Command != C_ACK) Header->Sequence = ++Sequence;
  1350.     BCOPY_W(Header->Version);
  1351.     BCOPY_W(Header->Command);
  1352.     BCOPY_W(Header->Sequence);
  1353.     if (Header->Command != C_NEW_USER_1 && Header->Command != C_NEW_USER_REG) {
  1354.       BCOPY_L(Header->UIN);
  1355.     }
  1356.     break;
  1357.   case 0x0005:
  1358.     switch(Header->Command) {
  1359.       case C_ACK:
  1360.         break;
  1361.       case C_KEEP_ALIVE:
  1362.         Header->Sequence = 0;
  1363.         Header->Sequence2 = ++Sequence2;
  1364.         break;
  1365.       default:
  1366.         Header->Sequence  = ++Sequence;
  1367.         Header->Sequence2 = ++Sequence2;
  1368.     }
  1369.     BCOPY_W(Header->Version);
  1370.     BCOPY_L(Zero);
  1371.     BCOPY_L(Header->UIN);
  1372.     BCOPY_L(Header->SessionID);
  1373.     BCOPY_W(Header->Command);
  1374.     BCOPY_W(Header->Sequence2);
  1375.     BCOPY_W(Header->Sequence);
  1376.     BCOPY_L(Header->CheckCode);
  1377.     break;
  1378. }
  1379.  
  1380. return(Len);
  1381.  
  1382. }
  1383.  
  1384.  
  1385. void UDP_ParseHeader(UBYTE *Buf, struct UDP_Header *Header)
  1386.  
  1387. {
  1388.  
  1389. UBYTE X1;
  1390.  
  1391. Len = 0;
  1392.  
  1393. ACOPY_W(Header->Version);
  1394.  
  1395. switch(Header->Version) {
  1396.   case 0x0002:
  1397.     ACOPY_W(Header->Command);
  1398.     ACOPY_W(Header->Sequence);
  1399.     break;
  1400.   case 0x0005:
  1401.     ACOPY_B(X1);
  1402.     ACOPY_L(Header->SessionID);
  1403.     ACOPY_W(Header->Command);
  1404.     ACOPY_W(Header->Sequence2);
  1405.     ACOPY_W(Header->Sequence);
  1406.     ACOPY_L(Header->UIN);
  1407.     ACOPY_L(Header->CheckCode);
  1408.     break;
  1409. }
  1410.  
  1411. return;
  1412.  
  1413. }
  1414.  
  1415.  
  1416. void PrintHex(UBYTE type, char *txt, UBYTE *buf, UWORD len)
  1417.  
  1418. {
  1419.  
  1420. char line[80], tmp[5];
  1421.  
  1422. int i, j;
  1423.  
  1424. UBYTE c;
  1425.  
  1426. if (txt) HandleError(type,txt);
  1427.  
  1428. for(i = 0; i<len; i += 8) {
  1429.   line[0] = '\0';
  1430.   for(j = 0; j<8; j++) {
  1431.     if (i+j >= len) strcat(line,"   ");
  1432.     else {
  1433.       c = (unsigned char)buf[i+j];
  1434.       sprintf(tmp,"%02x ",c);
  1435.       strcat(line,tmp);
  1436.     }
  1437.   }
  1438.   for(j = 0; j<8; j++) {
  1439.     if (i+j >= len) break;
  1440.     c = (unsigned char)buf[i+j];
  1441. //  if (c >= ' ' && c <= 'z') sprintf(tmp,"%c",c);
  1442.     if (c >= ' ') sprintf(tmp,"%c",c);
  1443.     else sprintf(tmp,".");
  1444.     strcat(line,tmp);
  1445.   }
  1446.   HandleError(type,line);
  1447.   if (j < 8) break;
  1448. }
  1449.  
  1450. return;
  1451.  
  1452. }
  1453.  
  1454.  
  1455. char *ICQ_CmdToText(UWORD cmd)
  1456.  
  1457. {
  1458.  
  1459. static char txt[50];
  1460.  
  1461. switch(cmd) {
  1462.   case TCP_MESSAGE:
  1463.     strcpy(txt,"TCP Message");
  1464.     break;
  1465.   case C_ACK:
  1466.     strcpy(txt,"ACK");
  1467.     break;
  1468.   case C_ACK_MSG:
  1469.     strcpy(txt,"Del Offline Msgs");
  1470.     break;
  1471.   case C_SEND_MESSAGE:
  1472.     strcpy(txt,"Send Message");
  1473.     break;
  1474.   case C_LOGIN:
  1475.     strcpy(txt,"Login");
  1476.     break;
  1477.   case C_CONTACT_LIST:
  1478.     strcpy(txt,"Contact List");
  1479.     break;
  1480.   case C_SEND_TEXT_CODE:
  1481.     strcpy(txt,"Client Logout");
  1482.     break;
  1483.   case C_LOGIN_1:
  1484.     strcpy(txt,"Unknown (Login 1)");
  1485.     break;
  1486.   case C_LOGIN_2:
  1487.     strcpy(txt,"Unknown (Login 2)");
  1488.     break;
  1489.   case C_INFO_REQ:
  1490.     strcpy(txt,"Info Request");
  1491.     break;
  1492.   case C_SEARCH_USER:
  1493.     strcpy(txt,"User Search");
  1494.     break;
  1495.   case C_CHANGE_PASSWORD:
  1496.     strcpy(txt,"Change Password");
  1497.     break;
  1498.   case C_STATUS_CHANGE:
  1499.     strcpy(txt,"Status Change");
  1500.     break;
  1501.   case C_QUERY_STATUS:
  1502.     strcpy(txt,"Query Servers");
  1503.     break;
  1504.   case C_SEND_URL_MESSAGE:
  1505.     strcpy(txt,"Request URL Message");
  1506.     break;
  1507.   case C_EXT_INFO_REQ:
  1508.     strcpy(txt,"Ext. Info Request");
  1509.     break;
  1510.   case C_META:
  1511.     strcpy(txt,"Meta Command");
  1512.     break;
  1513.   case C_UPDATE_INFO:
  1514.     strcpy(txt,"Update Basic Info");
  1515.     break;
  1516.   case C_NEW_USER_INFO:
  1517.     strcpy(txt,"New User Info");
  1518.     break;
  1519.   case C_UPDATE_EXT_INFO:
  1520.     strcpy(txt,"Update Ext. Info");
  1521.     break;
  1522.   case C_NEW_USER_1:
  1523.     strcpy(txt,"Request New User");
  1524.     break;
  1525.   case C_NEW_USER_REG:
  1526.     strcpy(txt,"Register New User");
  1527.     break;
  1528.   case C_UPDATE_AUTH:
  1529.     strcpy(txt,"Update Authorize");
  1530.     break;
  1531.   case C_VIS_LIST:
  1532.     strcpy(txt,"Visible List");
  1533.     break;
  1534.   case C_INVIS_LIST:
  1535.     strcpy(txt,"Invisible List");
  1536.     break;
  1537.   case C_KEEP_ALIVE:
  1538.     strcpy(txt,"Ping Server");
  1539.     break;
  1540.   case S_LOGIN_REPLY:
  1541.     strcpy(txt,"Login Reply");
  1542.     break;
  1543.   case S_USER_ONLINE:
  1544.     strcpy(txt,"User Online");
  1545.     break;
  1546.   case S_USER_OFFLINE:
  1547.     strcpy(txt,"User Offline");
  1548.     break;
  1549.   case S_RECEIVE_MESSAGE:
  1550.     strcpy(txt,"Receive Offline Message");
  1551.     break;
  1552.   case S_GET_MESSAGE:
  1553.     strcpy(txt,"Receive Online Message");
  1554.     break;
  1555.   case S_STATUS_UPDATE :
  1556.     strcpy(txt,"Status Update");
  1557.     break;
  1558.   case S_GO_AWAY:
  1559.     strcpy(txt,"Server Logout");
  1560.     break;
  1561.   case S_REPLY_X1:
  1562.     strcpy(txt,"End Online User List");
  1563.     break;
  1564.   case S_END_OFFLINE_MSGS:
  1565.     strcpy(txt,"No More Messages");
  1566.     break;
  1567.   case S_INFO_REPLY:
  1568.     strcpy(txt,"Reply User Info");
  1569.     break;
  1570.   case S_USER_FOUND:
  1571.     strcpy(txt,"User Found");
  1572.     break;
  1573.   case S_END_OF_SEARCH:
  1574.     strcpy(txt,"End Of Search");
  1575.     break;
  1576.   case S_QUERY_REPLY:
  1577.     strcpy(txt,"Query Reply");
  1578.     break;
  1579.   case S_EXT_INFO_REPLY:
  1580.     strcpy(txt,"Ext. Info Reply");
  1581.     break;
  1582.   case S_UPDATE_REPLY:
  1583.     strcpy(txt,"Update Info Reply");
  1584.     break;
  1585.   case S_UPDATE_EXT_REPLY:
  1586.     strcpy(txt,"Update Ext. Reply");
  1587.     break;
  1588.   case S_NEW_USER_REPLY:
  1589.     strcpy(txt,"New User Info Reply");
  1590.     break;
  1591.   case S_BAD_PASSWORD:
  1592.     strcpy(txt,"Bad Password");
  1593.     break;
  1594.   case S_NEW_USER_UIN:
  1595.     strcpy(txt,"New User UIN");
  1596.     break;
  1597.   case S_UPDATE_AUTH_REPLY:
  1598.     strcpy(txt,"Update Auth. Reply");
  1599.     break;
  1600.   case S_TOO_BUSY:
  1601.     strcpy(txt,"Server is Busy");
  1602.     break;
  1603.   case S_TCP_REQUEST:
  1604.     strcpy(txt,"TCP Information");
  1605.     break;
  1606.   case S_INFO_NOT_FOUND:
  1607.     strcpy(txt,"Info Not Found");
  1608.     break;
  1609.   case S_EXT_INFO_NOT_FOUND:
  1610.     strcpy(txt,"Ext. Info Not Found");
  1611.     break;
  1612.   case S_MULTI:
  1613.     strcpy(txt,"Multi-Packet");
  1614.     break;
  1615.   case S_META:
  1616.     strcpy(txt,"Meta Command Reply");
  1617.     break;
  1618.   default:
  1619.     sprintf(txt,"0x%04x",cmd);
  1620. }
  1621.  
  1622. return(txt);
  1623.  
  1624. }
  1625.