1152
|
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
2 /*
|
|
3 $Id: icqpacket.c 1162 2000-11-28 02:22:42Z warmenhoven $
|
|
4 $Log$
|
|
5 Revision 1.1 2000/11/28 02:22:42 warmenhoven
|
|
6 icq. whoop de doo
|
|
7
|
|
8 Revision 1.10 2000/07/07 15:26:35 denis
|
|
9 "icq_Packet data overflow" log message temporarily commented out.
|
|
10
|
|
11 Revision 1.9 2000/06/25 16:26:36 denis
|
|
12 icq_PacketUDPDump() tweaked a little.
|
|
13
|
|
14 Revision 1.8 2000/05/03 18:20:40 denis
|
|
15 icq_PacketReadUDPInUIN() was added.
|
|
16
|
|
17 Revision 1.7 2000/04/05 14:37:02 denis
|
|
18 Applied patch from "Guillaume R." <grs@mail.com> for basic Win32
|
|
19 compatibility.
|
|
20
|
|
21 Revision 1.6 2000/01/16 03:59:10 bills
|
|
22 reworked list code so list_nodes don't need to be inside item structures,
|
|
23 removed strlist code and replaced with generic list calls
|
|
24
|
|
25 Revision 1.5 1999/09/29 19:58:20 bills
|
|
26 cleanup
|
|
27
|
|
28 Revision 1.4 1999/09/29 16:56:10 denis
|
|
29 Cleanups.
|
|
30
|
|
31 Revision 1.3 1999/07/18 20:18:43 bills
|
|
32 changed to use new byte-order functions
|
|
33
|
|
34 Revision 1.2 1999/07/16 15:45:05 denis
|
|
35 Cleaned up.
|
|
36
|
|
37 Revision 1.1 1999/07/16 12:11:36 denis
|
|
38 UDP packet support added.
|
|
39 tcp_packet* functions renamed to icq_Packet*
|
|
40
|
|
41 Revision 1.8 1999/07/12 15:13:38 cproch
|
|
42 - added definition of ICQLINK to hold session-specific global variabled
|
|
43 applications which have more than one connection are now possible
|
|
44 - changed nearly every function defintion to support ICQLINK parameter
|
|
45
|
|
46 Revision 1.7 1999/07/03 06:33:52 lord
|
|
47 . byte order conversion macros added
|
|
48 . some compilation warnings removed
|
|
49
|
|
50 Revision 1.6 1999/04/17 19:36:50 bills
|
|
51 added tcp_packet_node_delete function and changed structure to include
|
|
52 list_node for new list routines.
|
|
53
|
|
54 Revision 1.5 1999/04/14 15:08:04 denis
|
|
55 Cleanups for "strict" compiling (-ansi -pedantic)
|
|
56
|
|
57 */
|
|
58
|
|
59 /*
|
|
60 * ICQ packet abstraction
|
|
61 */
|
|
62
|
|
63 #include <stdlib.h>
|
|
64 #include <sys/types.h>
|
|
65
|
|
66 #ifdef _WIN32
|
|
67 #include <winsock.h>
|
|
68 #else
|
|
69 #include <sys/socket.h>
|
|
70 #endif
|
|
71
|
|
72 #include "icqtypes.h"
|
|
73 #include "icq.h"
|
|
74 #include "icqlib.h"
|
|
75 #include "icqpacket.h"
|
|
76 #include "tcp.h"
|
|
77 #include "util.h"
|
|
78 #include "icqbyteorder.h"
|
|
79 #include "list.h"
|
|
80
|
|
81 icq_Packet *icq_PacketNew()
|
|
82 {
|
|
83 icq_Packet *p=(icq_Packet*)malloc(sizeof(icq_Packet));
|
|
84
|
|
85 p->length=0;
|
|
86 p->cursor=0;
|
|
87 p->id=0;
|
|
88
|
|
89 return p;
|
|
90 }
|
|
91
|
|
92 void icq_PacketDelete(void *p)
|
|
93 {
|
|
94 free(p);
|
|
95 }
|
|
96
|
|
97 void icq_PacketAppend32(icq_Packet *p, DWORD i)
|
|
98 {
|
|
99 DWORD val=i;
|
|
100
|
|
101 *(unsigned long*)((p->data)+(p->cursor))=htoicql(val);
|
|
102 icq_PacketAdvance(p, sizeof(DWORD));
|
|
103 }
|
|
104
|
|
105 void icq_PacketAppend32n(icq_Packet *p, DWORD i)
|
|
106 {
|
|
107 DWORD val=i;
|
|
108
|
|
109 *(DWORD *)((p->data)+(p->cursor)) = val;
|
|
110 icq_PacketAdvance(p, sizeof(DWORD));
|
|
111 }
|
|
112
|
|
113 DWORD icq_PacketRead32(icq_Packet *p)
|
|
114 {
|
|
115 DWORD val;
|
|
116
|
|
117 val = icqtohl(*(DWORD *)((p->data)+(p->cursor)));
|
|
118 icq_PacketAdvance(p, sizeof(DWORD));
|
|
119
|
|
120 return val;
|
|
121 }
|
|
122
|
|
123 DWORD icq_PacketRead32n(icq_Packet *p)
|
|
124 {
|
|
125 DWORD val;
|
|
126
|
|
127 val = *(DWORD*)((p->data)+(p->cursor));
|
|
128 icq_PacketAdvance(p, sizeof(DWORD));
|
|
129
|
|
130 return val;
|
|
131 }
|
|
132
|
|
133 void icq_PacketAppend16(icq_Packet *p, WORD i)
|
|
134 {
|
|
135 WORD val=i;
|
|
136
|
|
137 *(WORD *)((p->data)+(p->cursor)) = htoicqs(val);
|
|
138 icq_PacketAdvance(p, sizeof(WORD));
|
|
139 }
|
|
140
|
|
141 void icq_PacketAppend16n(icq_Packet *p, WORD i)
|
|
142 {
|
|
143 WORD val=i;
|
|
144
|
|
145 *(WORD *)((p->data)+(p->cursor)) = val;
|
|
146 icq_PacketAdvance(p, sizeof(WORD));
|
|
147 }
|
|
148
|
|
149 WORD icq_PacketRead16(icq_Packet *p)
|
|
150 {
|
|
151 WORD val;
|
|
152
|
|
153 val = icqtohs(*(WORD *)((p->data)+(p->cursor)));
|
|
154 icq_PacketAdvance(p, sizeof(WORD));
|
|
155
|
|
156 return val;
|
|
157 }
|
|
158
|
|
159 WORD icq_PacketRead16n(icq_Packet *p)
|
|
160 {
|
|
161 WORD val;
|
|
162
|
|
163 val = *(WORD*)((p->data)+(p->cursor));
|
|
164 icq_PacketAdvance(p, sizeof(WORD));
|
|
165
|
|
166 return val;
|
|
167 }
|
|
168
|
|
169 void icq_PacketAppend8(icq_Packet *p, BYTE i)
|
|
170 {
|
|
171 BYTE val=i;
|
|
172
|
|
173 memcpy((p->data)+(p->cursor), &val, sizeof(BYTE));
|
|
174 icq_PacketAdvance(p, sizeof(BYTE));
|
|
175 }
|
|
176
|
|
177 BYTE icq_PacketRead8(icq_Packet *p)
|
|
178 {
|
|
179 BYTE val;
|
|
180
|
|
181 memcpy(&val, (p->data)+(p->cursor), sizeof(BYTE));
|
|
182 icq_PacketAdvance(p, sizeof(BYTE));
|
|
183
|
|
184 return val;
|
|
185 }
|
|
186
|
|
187 void icq_PacketAppendString(icq_Packet *p, const char *s)
|
|
188 {
|
|
189 if(s)
|
|
190 {
|
|
191 int length=strlen(s)+1;
|
|
192
|
|
193 icq_PacketAppend16(p, length);
|
|
194 icq_PacketAppend(p, s, length);
|
|
195 }
|
|
196 else
|
|
197 {
|
|
198 icq_PacketAppend16(p, 1);
|
|
199 icq_PacketAppend8(p,0);
|
|
200 }
|
|
201 }
|
|
202
|
|
203 const char *icq_PacketReadString(icq_Packet *p)
|
|
204 {
|
|
205 int length=icq_PacketRead16(p);
|
|
206
|
|
207 return (const char *)icq_PacketRead(p, length);
|
|
208 }
|
|
209
|
|
210 char *icq_PacketReadStringNew(icq_Packet *p)
|
|
211 {
|
|
212 char *ptr;
|
|
213 int length=icq_PacketRead16(p);
|
|
214
|
|
215 ptr = (char*)malloc(length);
|
|
216 if(!ptr)
|
|
217 return 0L;
|
|
218 strncpy(ptr, icq_PacketRead(p, length), length);
|
|
219 return ptr;
|
|
220 }
|
|
221
|
|
222 void icq_PacketAppendStringFE(icq_Packet *p, const char *s)
|
|
223 {
|
|
224 if(s)
|
|
225 {
|
|
226 int length=strlen(s);
|
|
227 icq_PacketAppend(p, s, length);
|
|
228 }
|
|
229 icq_PacketAppend8(p, 0xFE);
|
|
230 }
|
|
231
|
|
232 void icq_PacketAppendString0(icq_Packet *p, const char *s)
|
|
233 {
|
|
234 if(s)
|
|
235 {
|
|
236 int length=strlen(s);
|
|
237 icq_PacketAppend(p, s, length);
|
|
238 }
|
|
239 icq_PacketAppend8(p, 0);
|
|
240 }
|
|
241
|
|
242 WORD icq_PacketReadUDPOutVer(icq_Packet *p)
|
|
243 {
|
|
244 icq_PacketGoto(p, 0);
|
|
245 return icq_PacketRead16(p);
|
|
246 }
|
|
247
|
|
248 WORD icq_PacketReadUDPOutCmd(icq_Packet *p)
|
|
249 {
|
|
250 icq_PacketGoto(p, 14 /*2*/);
|
|
251 return icq_PacketRead16(p);
|
|
252 }
|
|
253
|
|
254 WORD icq_PacketReadUDPOutSeq1(icq_Packet *p)
|
|
255 {
|
|
256 icq_PacketGoto(p, 16);
|
|
257 return icq_PacketRead16(p);
|
|
258 }
|
|
259
|
|
260 WORD icq_PacketReadUDPOutSeq2(icq_Packet *p)
|
|
261 {
|
|
262 icq_PacketGoto(p, 18 /*4*/);
|
|
263 return icq_PacketRead16(p);
|
|
264 }
|
|
265
|
|
266 WORD icq_PacketReadUDPInVer(icq_Packet *p)
|
|
267 {
|
|
268 icq_PacketGoto(p, 0);
|
|
269 return icq_PacketRead16(p);
|
|
270 }
|
|
271
|
|
272 WORD icq_PacketReadUDPInCmd(icq_Packet *p)
|
|
273 {
|
|
274 icq_PacketGoto(p, 7);
|
|
275 return icq_PacketRead16(p);
|
|
276 }
|
|
277
|
|
278 WORD icq_PacketReadUDPInSeq1(icq_Packet *p)
|
|
279 {
|
|
280 icq_PacketGoto(p, 9);
|
|
281 return icq_PacketRead16(p);
|
|
282 }
|
|
283
|
|
284 WORD icq_PacketReadUDPInSeq2(icq_Packet *p)
|
|
285 {
|
|
286 icq_PacketGoto(p, 11);
|
|
287 return icq_PacketRead16(p);
|
|
288 }
|
|
289
|
|
290 DWORD icq_PacketReadUDPInUIN(icq_Packet *p)
|
|
291 {
|
|
292 icq_PacketGoto(p, 13);
|
|
293 return icq_PacketRead32(p);
|
|
294 }
|
|
295
|
|
296 void icq_PacketAppend(icq_Packet *p, const void *data, int length)
|
|
297 {
|
|
298 memcpy((p->data)+(p->cursor), data, length);
|
|
299 icq_PacketAdvance(p, length);
|
|
300 }
|
|
301
|
|
302 const void *icq_PacketRead(icq_Packet *p, int length)
|
|
303 {
|
|
304 const void *data=(p->data)+(p->cursor);
|
|
305
|
|
306 icq_PacketAdvance(p, length);
|
|
307
|
|
308 return data;
|
|
309 }
|
|
310
|
|
311 void icq_PacketShortDump(icq_Packet *p)
|
|
312 {
|
|
313 printf("icq_Packet %x { id=%d, cursor=%x, length=%d }\n",
|
|
314 (int)p, (int)p->id, p->cursor, p->length);
|
|
315 }
|
|
316
|
|
317 void icq_PacketDump(icq_Packet *p)
|
|
318 {
|
|
319 icq_PacketShortDump(p);
|
|
320 hex_dump((char*)&(p->length), p->length+sizeof(WORD));
|
|
321 }
|
|
322
|
|
323 void icq_PacketUDPDump(icq_Packet *p)
|
|
324 {
|
|
325 icq_PacketShortDump(p);
|
|
326 hex_dump((char*)&(p->data), p->length);
|
|
327 }
|
|
328
|
|
329 void icq_PacketBegin(icq_Packet *p)
|
|
330 {
|
|
331 p->cursor=0;
|
|
332 }
|
|
333
|
|
334 void icq_PacketEnd(icq_Packet *p)
|
|
335 {
|
|
336 p->cursor=p->length;
|
|
337 }
|
|
338
|
|
339 void icq_PacketAdvance(icq_Packet *p, int i)
|
|
340 {
|
|
341 p->cursor+=i;
|
|
342
|
|
343 if(p->cursor > p->length)
|
|
344 p->length=p->cursor;
|
|
345
|
|
346 /* Do nothing, because we don't have ICQLINK here */
|
|
347 /* if(p->cursor > ICQ_PACKET_DATA_SIZE) */
|
|
348 /* icq_FmtLog(0L, ICQ_LOG_WARNING, "icq_Packet data overflow\n"); */
|
|
349 }
|
|
350
|
|
351 void icq_PacketGoto(icq_Packet *p, int i)
|
|
352 {
|
|
353 icq_PacketBegin(p);
|
|
354 icq_PacketAdvance(p, i);
|
|
355 }
|
|
356
|
|
357 void icq_PacketGotoUDPOutData(icq_Packet *p, int i)
|
|
358 {
|
|
359 /* Go to data in UDP _client_ packet. */
|
|
360 icq_PacketGoto(p, 24+i);
|
|
361 }
|
|
362
|
|
363 void icq_PacketGotoUDPInData(icq_Packet *p, int i)
|
|
364 {
|
|
365 /* Go to data in UDP _server_ packet. */
|
|
366 icq_PacketGoto(p, 21+i);
|
|
367 }
|
|
368
|
|
369 WORD icq_PacketPos(icq_Packet *p)
|
|
370 {
|
|
371 return p->cursor;
|
|
372 }
|
|
373
|
|
374 int icq_PacketSend(icq_Packet *p, int socket)
|
|
375 {
|
|
376 int result;
|
|
377
|
|
378 result=send(socket, (const char*)&(p->length), p->length+sizeof(WORD), 0);
|
|
379
|
|
380 #ifdef TCP_RAW_TRACE
|
|
381 printf("%d bytes sent on socket %d, result %d\n",
|
|
382 p->length+1, socket, result);
|
|
383 icq_PacketDump(p);
|
|
384 #endif /* TCP_RAW_TRACE */
|
|
385
|
|
386 return result;
|
|
387 }
|