[gaim-migrate @ 3063]
[pidgin-git.git] / src / protocols / icq / icqpacket.c
blob0da0a3d14db92f84442f37e75d489a0c02625ab3
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
3 /*
4 * $Id: icqpacket.c 2487 2001-10-10 19:58:11Z warmenhoven $
6 * Copyright (C) 1998-2001, Denis V. Dmitrienko <denis@null.net> and
7 * Bill Soudan <soudan@kde.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 * ICQ packet abstraction
29 #include <stdlib.h>
31 #ifdef _WIN32
32 #include <winsock.h>
33 #else
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #endif
38 #include "icqlib.h"
39 #include "tcp.h"
40 #include "icqbyteorder.h"
42 icq_Packet *icq_PacketNew()
44 icq_Packet *p=(icq_Packet*)malloc(sizeof(icq_Packet));
46 p->length=0;
47 p->cursor=0;
48 p->id=0;
50 return p;
53 void icq_PacketDelete(void *p)
55 free(p);
58 void icq_PacketAppend32(icq_Packet *p, DWORD i)
60 DWORD val=i;
62 val = htoicql(val);
63 memcpy((p->data)+(p->cursor),&val,sizeof(DWORD));
64 icq_PacketAdvance(p, sizeof(DWORD));
67 void icq_PacketAppend32n(icq_Packet *p, DWORD i)
69 DWORD val=i;
71 memcpy((p->data)+(p->cursor),&val,sizeof(DWORD));
72 icq_PacketAdvance(p, sizeof(DWORD));
75 DWORD icq_PacketRead32(icq_Packet *p)
77 DWORD val;
79 memcpy(&val,(p->data)+(p->cursor),sizeof(DWORD));
80 val = icqtohl(val);
81 icq_PacketAdvance(p, sizeof(DWORD));
83 return val;
86 DWORD icq_PacketRead32n(icq_Packet *p)
88 DWORD val;
90 memcpy(&val,(p->data)+(p->cursor),sizeof(DWORD));
91 icq_PacketAdvance(p, sizeof(DWORD));
93 return val;
96 void icq_PacketAppend16(icq_Packet *p, WORD i)
98 WORD val=i;
100 val = htoicqs(val);
101 memcpy((p->data)+(p->cursor),&val,sizeof(WORD));
102 icq_PacketAdvance(p, sizeof(WORD));
105 void icq_PacketAppend16n(icq_Packet *p, WORD i)
107 WORD val=i;
109 memcpy((p->data)+(p->cursor),&val,sizeof(WORD));
110 icq_PacketAdvance(p, sizeof(WORD));
113 WORD icq_PacketRead16(icq_Packet *p)
115 WORD val;
117 memcpy(&val,(p->data)+(p->cursor),sizeof(WORD));
118 val = icqtohs(val);
119 icq_PacketAdvance(p, sizeof(WORD));
121 return val;
124 WORD icq_PacketRead16n(icq_Packet *p)
126 WORD val;
128 memcpy(&val,(p->data)+(p->cursor),sizeof(WORD));
129 icq_PacketAdvance(p, sizeof(WORD));
131 return val;
134 void icq_PacketAppend8(icq_Packet *p, BYTE i)
136 BYTE val=i;
138 memcpy((p->data)+(p->cursor), &val, sizeof(BYTE));
139 icq_PacketAdvance(p, sizeof(BYTE));
142 BYTE icq_PacketRead8(icq_Packet *p)
144 BYTE val;
146 memcpy(&val, (p->data)+(p->cursor), sizeof(BYTE));
147 icq_PacketAdvance(p, sizeof(BYTE));
149 return val;
152 void icq_PacketAppendString(icq_Packet *p, const char *s)
154 if(s)
156 int length=strlen(s)+1;
158 icq_PacketAppend16(p, length);
159 icq_PacketAppend(p, s, length);
161 else
163 icq_PacketAppend16(p, 1);
164 icq_PacketAppend8(p,0);
168 const char *icq_PacketReadString(icq_Packet *p)
170 int length=icq_PacketRead16(p);
172 return (const char *)icq_PacketRead(p, length);
175 char *icq_PacketReadStringNew(icq_Packet *p)
177 char *ptr;
178 int length=icq_PacketRead16(p);
180 ptr = (char*)malloc(length);
181 if(!ptr)
182 return 0L;
183 strncpy(ptr, icq_PacketRead(p, length), length);
184 return ptr;
187 void icq_PacketAppendStringFE(icq_Packet *p, const char *s)
189 if(s)
191 int length=strlen(s);
192 icq_PacketAppend(p, s, length);
194 icq_PacketAppend8(p, 0xFE);
197 void icq_PacketAppendString0(icq_Packet *p, const char *s)
199 if(s)
201 int length=strlen(s);
202 icq_PacketAppend(p, s, length);
204 icq_PacketAppend8(p, 0);
207 WORD icq_PacketReadUDPOutVer(icq_Packet *p)
209 icq_PacketGoto(p, 0);
210 return icq_PacketRead16(p);
213 WORD icq_PacketReadUDPOutCmd(icq_Packet *p)
215 icq_PacketGoto(p, 14 /*2*/);
216 return icq_PacketRead16(p);
219 WORD icq_PacketReadUDPOutSeq1(icq_Packet *p)
221 icq_PacketGoto(p, 16);
222 return icq_PacketRead16(p);
225 WORD icq_PacketReadUDPOutSeq2(icq_Packet *p)
227 icq_PacketGoto(p, 18 /*4*/);
228 return icq_PacketRead16(p);
231 WORD icq_PacketReadUDPInVer(icq_Packet *p)
233 icq_PacketGoto(p, 0);
234 return icq_PacketRead16(p);
237 WORD icq_PacketReadUDPInCmd(icq_Packet *p)
239 icq_PacketGoto(p, 7);
240 return icq_PacketRead16(p);
243 WORD icq_PacketReadUDPInCmdV3(icq_Packet *p)
245 icq_PacketGoto(p, 2);
246 return icq_PacketRead16(p);
249 WORD icq_PacketReadUDPInSeq1(icq_Packet *p)
251 icq_PacketGoto(p, 9);
252 return icq_PacketRead16(p);
255 WORD icq_PacketReadUDPInSeq2(icq_Packet *p)
257 icq_PacketGoto(p, 11);
258 return icq_PacketRead16(p);
261 DWORD icq_PacketReadUDPInUIN(icq_Packet *p)
263 icq_PacketGoto(p, 13);
264 return icq_PacketRead32(p);
267 void icq_PacketAppend(icq_Packet *p, const void *data, int length)
269 memcpy((p->data)+(p->cursor), data, length);
270 icq_PacketAdvance(p, length);
273 const void *icq_PacketRead(icq_Packet *p, int length)
275 const void *data=(p->data)+(p->cursor);
277 icq_PacketAdvance(p, length);
279 return data;
282 void icq_PacketShortDump(icq_Packet *p)
284 printf("icq_Packet %lx { id=%d, cursor=%x, length=%d }\n",
285 (long)p, (int)p->id, p->cursor, p->length);
288 void icq_PacketDump(icq_Packet *p)
290 icq_PacketShortDump(p);
291 hex_dump((char*)&(p->length), p->length+sizeof(WORD));
294 void icq_PacketUDPDump(icq_Packet *p)
296 icq_PacketShortDump(p);
297 hex_dump((char*)&(p->data), p->length);
300 void icq_PacketBegin(icq_Packet *p)
302 p->cursor=0;
305 void icq_PacketEnd(icq_Packet *p)
307 p->cursor=p->length;
310 void icq_PacketAdvance(icq_Packet *p, int i)
312 p->cursor+=i;
314 if(p->cursor > p->length)
315 p->length=p->cursor;
317 /* Do nothing, because we don't have ICQLINK here */
318 /* if(p->cursor > ICQ_PACKET_DATA_SIZE) */
319 /* icq_FmtLog(0L, ICQ_LOG_WARNING, "icq_Packet data overflow\n"); */
322 void icq_PacketGoto(icq_Packet *p, int i)
324 icq_PacketBegin(p);
325 icq_PacketAdvance(p, i);
328 void icq_PacketGotoUDPOutData(icq_Packet *p, int i)
330 /* Go to data in UDP _client_ packet. */
331 icq_PacketGoto(p, 24+i);
334 void icq_PacketGotoUDPInData(icq_Packet *p, int i)
336 /* Go to data in UDP _server_ packet. */
337 icq_PacketGoto(p, 21+i);
340 WORD icq_PacketPos(icq_Packet *p)
342 return p->cursor;
345 int icq_PacketSend(icq_Packet *p, int socket_fd)
347 int result;
349 result=send(socket_fd, (const char*)&(p->length), p->length+sizeof(WORD), 0);
351 #ifdef TCP_RAW_TRACE
352 printf("%d bytes sent on socket %d, result %d\n",
353 p->length+1, socket, result);
354 icq_PacketDump(p);
355 #endif /* TCP_RAW_TRACE */
357 return result;