1
2
3 /*
4 * Assemble outgoing and dissect incoming packets.
5 *
6 * climm Copyright (C) © 2001-2007 Rüdiger Kuhlmann
7 *
8 * climm is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 dated June, 1991.
11 *
12 * climm is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 * License for more details.
16 *
17 * In addition, as a special exception permission is granted to link the
18 * code of this release of climm with the OpenSSL project's "OpenSSL"
19 * library, and distribute the linked executables. You must obey the GNU
20 * General Public License in all respects for all of the code used other
21 * than "OpenSSL". If you modify this file, you may extend this exception
22 * to your version of the file, but you are not obligated to do so. If you
23 * do not wish to do so, delete this exception statement from your version
24 * of this file.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this package; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
29 * 02111-1307, USA.
30 *
31 * $Id: packet.c 2770 2009-04-01 16:26:43Z kuhlmann $
32 *
33 * Note: alle read strings need to be free()ed.
34 */
35
36 #include "climm.h"
37 #include "packet.h"
38 #include "preferences.h"
39 #include "util_ui.h"
40 #include "contact.h"
41 #include "buildmark.h"
42 #include <assert.h>
43
44 #define cap_id "\x82\x22\x44\x45\x53\x54\x00\x00"
45 #define cap_none "\x00\x00\x00\x00\x00\x00\x00\x00"
46 #define cap_str "\xbc\xd2\x00\x04\xac\x96\xdd\x96"
47
48 #define cap_mid "\x4c\x7f\x11\xd1"
49 #define cap_mstr "\x4f\xe9\xd3\x11"
50 #define cap_aim "\x09\x46\x13"
51
52 static Cap caps[CAP_MAX] =
53 {
54 { CAP_NONE, 16, cap_none cap_none, "CAP_NONE", NULL },
55 /* AIM capabilities */
56 { CAP_AIM_VOICE, 16, cap_aim "\x41" cap_mid cap_id, "CAP_AIM_VOICE", NULL },
57 { CAP_AIM_SFILE, 16, cap_aim "\x43" cap_mid cap_id, "CAP_AIM_SFILE", NULL },
58 { CAP_REVCONNREQ, 16, cap_aim "\x44" cap_mid cap_id, "CAP_REVCONNREQ", NULL },
59 { CAP_AIM_IMIMAGE, 16, cap_aim "\x45" cap_mid cap_id, "CAP_AIM_IMIMAGE", NULL },
60 { CAP_AIM_BUDICON, 16, cap_aim "\x46" cap_mid cap_id, "CAP_AIM_BUDICON", NULL },
61 { CAP_AIM_STOCKS, 16, cap_aim "\x47" cap_mid cap_id, "CAP_AIM_STOCKS", NULL },
62 { CAP_AIM_GETFILE, 16, cap_aim "\x48" cap_mid cap_id, "CAP_AIM_GETFILE", NULL },
63 { CAP_SRVRELAY, 16, cap_aim "\x49" cap_mid cap_id, "CAP_SRVRELAY", NULL },
64 { CAP_AIM_GAMES, 16, cap_aim "\x4a" cap_mid cap_id, "CAP_AIM_GAMES", NULL },
65 { CAP_AIM_SBUD, 16, cap_aim "\x4b" cap_mid cap_id, "CAP_AIM_SBUD", NULL },
66 { CAP_AIM_INTER, 16, cap_aim "\x4d" cap_mid cap_id, "CAP_AIM_INTER", NULL },
67 { CAP_AVATAR, 16, cap_aim "\x4c" cap_mid cap_id, "CAP_AVATAR", NULL },
68 { CAP_UTF8, 16, cap_aim "\x4e" cap_mid cap_id, "CAP_UTF8", NULL },
69 /* ICQ capabilities */
70 { CAP_RTFMSGS, 16, "\x97\xb1\x27\x51\x24\x3c\x43\x34\xad\x22\xd6\xab\xf7\x3f\x14\x92", "CAP_RTFMSGS", NULL },
71 { CAP_IS_2001, 16, "\x2e\x7a\x64\x75\xfa\xdf\x4d\xc8\x88\x6f\xea\x35\x95\xfd\xb6\xdf", "CAP_IS_2001", NULL },
72 { CAP_STR_2001, 16, "\xa0\xe9\x3f\x37" cap_mstr cap_str, "CAP_STR_2001", NULL }, /* PSIG_INFO_PLUGIN_s PMSG_QUERY_INFO_s */
73 { CAP_STR_2002, 16, "\x10\xcf\x40\xd1" cap_mstr cap_str, "CAP_STR_2002", NULL }, /* PSIG_STATUS_PLUGIN_s PMSG_QUERY_STATUS_s */
74 { CAP_AIM_CHAT, 16, "\x74\x8f\x24\x20\x62\x87\x11\xd1" cap_id, "CAP_AIM_CHAT", NULL },
75 { CAP_TYPING, 16, "\x56\x3f\xc8\x09\x0b\x6f\x41\xbd\x9f\x79\x42\x26\x09\xdf\xa2\xf3", "CAP_TYPING", NULL },
76 { CAP_XTRAZ, 16, "\x1a\x09\x3c\x6c\xd7\xfd\x4e\xc5\x9d\x51\xa6\x47\x4e\x34\xf5\xa0", "CAP_XTRAZ", NULL },
77 /* client detection capabilities */
78 { CAP_TRILL_CRYPT, 16, "\xf2\xe7\xc7\xf4\xfe\xad\x4d\xfb\xb2\x35\x36\x79\x8b\xdf\x00\x00", "CAP_TRILL_CRYPT", NULL },
79 { CAP_TRILL_2, 16, "\x97\xb1\x27\x51\x24\x3c\x43\x34\xad\x22\xd6\xab\xf7\x3f\x14\x09", "CAP_TRILL_2", NULL },
80 { CAP_LICQ, 16, "\x09\x49\x13\x49" cap_mid cap_id, "CAP_LICQ", NULL },
81 { CAP_LICQNEW, 12, "Licq client \x00\x00\x00\x00", "CAP_LICQNEW", NULL },
82 { CAP_SIM, 15, "\x97\xb1\x27\x51\x24\x3c\x43\x34\xad\x22\xd6\xab\xf7\x3f\x14\x48", "CAP_SIM", NULL },
83 { CAP_SIMNEW, 12, "SIM client \x00\x00\x00\x00", "CAP_SIMNEW", NULL },
84 { CAP_MACICQ, 16, "\xdd\x16\xf2\x02\x84\xe6\x11\xd4\x90\xdb\x00\x10\x4b\x9b\x4b\x7d", "CAP_MACICQ", NULL },
85 { CAP_CLIMM, 12, "climm\xa9 R.K. \x00\x00\x00\x00", "CAP_CLIMM", NULL },
86 { CAP_MICQ, 12, "mICQ \xa9 R.K. \x00\x00\x00\x00", "CAP_MICQ", NULL },
87 { CAP_KXICQ, 16, "\x09\x49\x13\x44" cap_mid cap_id, "CAP_KXICQ", NULL },
88 { CAP_KOPETE, 12, "Kopete ICQ \x00\x00\x00\x00", "CAP_KOPETE", NULL },
89 { CAP_IMSECURE, 12, "IMsecureCphr\x00\x00\x00\x00", "CAP_IMSECURE", NULL },
90 { CAP_ARQ, 9, "&RQinside\x00\x00\x00\x00\x00\x00\x00", "CAP_ARQ", NULL },
91 { CAP_MIRANDA, 8, "MirandaM\x00\x00\x00\x00\x00\x00\x00\x00", "CAP_MIRANDA", NULL },
92 { CAP_QIP, 16, "\x56\x3f\xc8\x09\x0b\x6f\x41QIP 2005a", "CAP_QIP", NULL },
93 { CAP_IM2, 16, "\x74\xed\xc3\x36\x44\xdf\x48\x5b\x8b\x1c\x67\x1a\x1f\x86\x09\x9f", "CAP_IM2", NULL },
94 /* Unknown capabilities */
95 { CAP_UTF8ii, 16, cap_aim "\x4e" cap_mid "\x82\x22\x44\x45\x53\x54ii", "CAP_UTF82", NULL },
96 { CAP_WIERD1, 16, "\x17\x8c\x2d\x9b\xda\xa5\x45\xbb\x8d\xdb\xf3\xbd\xbd\x53\xa1\x0a", "CAP_WIERD1", NULL },
97 { CAP_WIERD3, 16, "\x67\x36\x15\x15\x61\x2d\x4c\x07\x8f\x3d\xbd\xe6\x40\x8e\xa0\x41", "CAP_WIERD3", NULL },
98 { CAP_WIERD4, 16, "\xe3\x62\xc1\xe9\x12\x1a\x4b\x94\xa6\x26\x7a\x74\xde\x24\x27\x0d", "CAP_WIERD4", NULL },
99 { CAP_WIERD5, 16, "\xb9\x97\x08\xb5\x3a\x92\x42\x02\xb0\x69\xf1\xe7\x57\xbb\x2e\x17", "CAP_WIERD5", NULL },
100 { CAP_WIERD7, 16, "\xb6\x07\x43\x78\xf5\x0c\x4a\xc7\x90\x92\x59\x38\x50\x2d\x05\x91", "CAP_WIERD7", NULL },
101 { CAP_11, 16, "\x01\x01\x01\x01\x01\x01\x19\x04\x4a\x16\xed\x79\x2c\xb1\x71\x01", "CAP_11", NULL },
102 { CAP_12, 16, "\x02\x02\x02\x02\x02\x02\xb3\xf8\x53\x44\x7f\x0d\x2d\x83\xbd\x76", "CAP_12", NULL },
103
104 { 0, 0, NULL, NULL, NULL }
105 };
106
107 static str_s packetstr[] =
108 {
109 { NULL, 0, 0 },
110 { NULL, 0, 0 },
111 { NULL, 0, 0 },
112 { NULL, 0, 0 },
113 { "<invalidlen>", 12, 0 },
114 { "", 0, 0 },
115 };
116
117 static int packetstrind = 0;
118
119 #define PACKETMAXSTR 4
120 #define PACKETSTRINVALID 4
121 #define PACKETSTREMPTY 5
122
123 #undef PacketC
PacketC(DEBUG0PARAM)124 Packet *PacketC (DEBUG0PARAM)
125 {
126 Packet *pak;
127
128 pak = calloc (1, sizeof (Packet));
129 assert (pak);
130
131 Debug (DEB_PACKET, "<--- %p new", pak);
132 uiG.packets++;
133
134 return pak;
135 }
136
137 #undef PacketCreate
PacketCreate(str_t str DEBUGPARAM)138 Packet *PacketCreate (str_t str DEBUGPARAM)
139 {
140 Packet *newpak;
141
142 newpak = calloc (1, sizeof (Packet));
143 assert (newpak);
144
145 memcpy (newpak->data, str->txt, str->len);
146 newpak->len = str->len;
147
148 Debug (DEB_PACKET, "<-+- %p create", newpak);
149 uiG.packets++;
150
151 return newpak;
152 }
153
154 #undef PacketD
PacketD(Packet * pak DEBUGPARAM)155 void PacketD (Packet *pak DEBUGPARAM)
156 {
157 Debug (DEB_PACKET, "---> %p free", pak);
158 uiG.packets--;
159 free (pak);
160 }
161
162 #undef PacketClone
PacketClone(const Packet * pak DEBUGPARAM)163 Packet *PacketClone (const Packet *pak DEBUGPARAM)
164 {
165 Packet *newpak;
166
167 newpak = malloc (sizeof (Packet));
168 assert (newpak);
169
170 memcpy (newpak, pak, sizeof (Packet));
171 newpak->rpos = 0;
172
173 Debug (DEB_PACKET, "<-+- %p clone %p", newpak, pak);
174 uiG.packets++;
175
176 return newpak;
177 }
178
PacketWrite1(Packet * pak,UBYTE data)179 void PacketWrite1 (Packet *pak, UBYTE data)
180 {
181 assert (pak);
182 assert (pak->wpos < PacketMaxData);
183
184 pak->data[pak->wpos++] = data;
185 if (pak->wpos > pak->len)
186 pak->len = pak->wpos;
187 }
188
PacketWrite2(Packet * pak,UWORD data)189 void PacketWrite2 (Packet *pak, UWORD data)
190 {
191 assert (pak);
192 assert (pak->wpos + 1 < PacketMaxData);
193
194 pak->data[pak->wpos++] = data & 0xff; data >>= 8;
195 pak->data[pak->wpos++] = data;
196 if (pak->wpos > pak->len)
197 pak->len = pak->wpos;
198 }
199
PacketWriteB2(Packet * pak,UWORD data)200 void PacketWriteB2 (Packet *pak, UWORD data)
201 {
202 assert (pak);
203 assert (pak->wpos + 1 < PacketMaxData);
204
205 pak->data[pak->wpos++] = data >> 8;
206 pak->data[pak->wpos++] = data & 0xff;
207 if (pak->wpos > pak->len)
208 pak->len = pak->wpos;
209 }
210
PacketWrite4(Packet * pak,UDWORD data)211 void PacketWrite4 (Packet *pak, UDWORD data)
212 {
213 assert (pak);
214 assert (pak->wpos + 3 < PacketMaxData);
215
216 pak->data[pak->wpos++] = data & 0xff; data >>= 8;
217 pak->data[pak->wpos++] = data & 0xff; data >>= 8;
218 pak->data[pak->wpos++] = data & 0xff; data >>= 8;
219 pak->data[pak->wpos++] = data;
220 if (pak->wpos > pak->len)
221 pak->len = pak->wpos;
222 }
223
PacketWriteB4(Packet * pak,UDWORD data)224 void PacketWriteB4 (Packet *pak, UDWORD data)
225 {
226 assert (pak);
227 assert (pak->wpos + 3 < PacketMaxData);
228
229 pak->data[pak->wpos++] = data >> 24;
230 pak->data[pak->wpos++] = (data >> 16) & 0xff;
231 pak->data[pak->wpos++] = (data >> 8) & 0xff;
232 pak->data[pak->wpos++] = data & 0xff;
233 if (pak->wpos > pak->len)
234 pak->len = pak->wpos;
235 }
236
PacketWriteCapID(Packet * pak,UBYTE id)237 void PacketWriteCapID (Packet *pak, UBYTE id)
238 {
239 UBYTE i;
240
241 assert (pak);
242 assert (id < CAP_MAX);
243
244 if (caps[id].id == id)
245 {
246 if (id == CAP_CLIMM || id == CAP_MICQ)
247 {
248 PacketWriteData (pak, (const char *)caps[id].cap, 12);
249 PacketWriteB4 (pak, BuildVersionNum);
250 }
251 else
252 PacketWriteData (pak, (const char *)caps[id].cap, 16);
253 return;
254 }
255
256 for (i = 0; i < CAP_MAX; i++)
257 if (caps[i].id == id)
258 break;
259
260 i %= CAP_MAX;
261 PacketWriteData (pak, (const char *)caps[i].cap, 16);
262 }
263
PacketWriteCap(Packet * pak,Cap * cap)264 void PacketWriteCap (Packet *pak, Cap *cap)
265 {
266 assert (pak);
267 assert (cap);
268
269 PacketWriteData (pak, (cap->var ? (const char *)cap->var : cap->cap), 16);
270 }
271
PacketWriteData(Packet * pak,const char * data,UWORD len)272 void PacketWriteData (Packet *pak, const char *data, UWORD len)
273 {
274 assert (pak);
275 assert (pak->wpos + len < PacketMaxData);
276
277 memcpy (pak->data + pak->wpos, data, len);
278 pak->wpos += len;
279 if (pak->wpos > pak->len)
280 pak->len = pak->wpos;
281 }
282
PacketWriteStr(Packet * pak,const char * data)283 void PacketWriteStr(Packet *pak, const char *data)
284 {
285 if (data)
286 PacketWriteData (pak, data, strlen (data));
287 }
288
PacketWriteLNTS(Packet * pak,const char * data)289 void PacketWriteLNTS (Packet *pak, const char *data)
290 {
291 data = data ? data : "";
292
293 assert (pak);
294 assert (pak->wpos + 3 + strlen (data) < PacketMaxData);
295
296 PacketWrite2 (pak, strlen (data) + 1);
297 PacketWriteData (pak, data, strlen (data));
298 PacketWrite1 (pak, 0);
299 }
300
PacketWriteLNTS2(Packet * pak,str_t text)301 void PacketWriteLNTS2 (Packet *pak, str_t text)
302 {
303 int len = text ? text->len : 0;
304 char *data = text ? text->txt : "";
305
306 assert (pak);
307 assert (pak->wpos + 3 + len < PacketMaxData);
308
309 PacketWrite2 (pak, len + 1);
310 PacketWriteData (pak, data, len);
311 PacketWrite1 (pak, 0);
312 }
313
PacketWriteDLStr(Packet * pak,const char * data)314 void PacketWriteDLStr (Packet *pak, const char *data)
315 {
316 data = data ? data : "";
317
318 assert (pak);
319 assert (pak->wpos + 4 + strlen (data) < PacketMaxData);
320
321 PacketWrite4 (pak, strlen (data));
322 PacketWriteData (pak, data, strlen (data));
323 }
324
PacketWriteLLNTS(Packet * pak,const char * data)325 void PacketWriteLLNTS (Packet *pak, const char *data)
326 {
327 data = data ? data : "";
328
329 assert (pak);
330 assert (pak->wpos + 5 + strlen (data) < PacketMaxData);
331
332 PacketWrite2 (pak, strlen (data) + 3);
333 PacketWrite2 (pak, strlen (data) + 1);
334 PacketWriteData (pak, data, strlen (data));
335 PacketWrite1 (pak, 0);
336 }
337
PacketWriteCont(Packet * pak,Contact * cont)338 void PacketWriteCont (Packet *pak, Contact *cont)
339 {
340 int len = strlen (cont->screen);
341 PacketWrite1 (pak, len);
342 PacketWriteData (pak, cont->screen, len);
343 }
344
PacketWriteTLV(Packet * pak,UDWORD type)345 void PacketWriteTLV (Packet *pak, UDWORD type)
346 {
347 UWORD pos;
348
349 PacketWriteB2 (pak, type);
350 pos = pak->wpos;
351 PacketWriteB2 (pak, pak->tpos); /* will be length */
352 pak->tpos = pos;
353 }
354
PacketWriteTLVDone(Packet * pak)355 void PacketWriteTLVDone (Packet *pak)
356 {
357 UWORD pos;
358
359 pos = PacketReadAtB2 (pak, pak->tpos);
360 PacketWriteAtB2 (pak, pak->tpos, pak->wpos - pak->tpos - 2);
361 pak->tpos = pos;
362 }
363
PacketWriteLen(Packet * pak)364 void PacketWriteLen (Packet *pak)
365 {
366 UWORD pos;
367
368 pos = pak->wpos;
369 PacketWriteB2 (pak, pak->tpos); /* will be length */
370 pak->tpos = pos;
371 }
372
PacketWriteLenDone(Packet * pak)373 void PacketWriteLenDone (Packet *pak)
374 {
375 UWORD pos;
376
377 pos = PacketReadAtB2 (pak, pak->tpos);
378 PacketWriteAt2 (pak, pak->tpos, pak->wpos - pak->tpos - 2);
379 pak->tpos = pos;
380 }
381
PacketWriteBLenDone(Packet * pak)382 void PacketWriteBLenDone (Packet *pak)
383 {
384 UWORD pos;
385
386 pos = PacketReadAtB2 (pak, pak->tpos);
387 PacketWriteAtB2 (pak, pak->tpos, pak->wpos - pak->tpos - 2);
388 pak->tpos = pos;
389 }
390
PacketWriteLen4(Packet * pak)391 void PacketWriteLen4 (Packet *pak)
392 {
393 UWORD pos;
394
395 pos = pak->wpos;
396 PacketWrite4 (pak, pak->tpos); /* will be length */
397 pak->tpos = pos;
398 }
399
PacketWriteLen4Done(Packet * pak)400 void PacketWriteLen4Done (Packet *pak)
401 {
402 UWORD pos;
403
404 pos = PacketReadAt4 (pak, pak->tpos);
405 PacketWriteAt4 (pak, pak->tpos, pak->wpos - pak->tpos - 4);
406 pak->tpos = pos;
407 }
408
PacketWritePos(const Packet * pak)409 UWORD PacketWritePos (const Packet *pak)
410 {
411 return pak->wpos;
412 }
413
PacketWriteAt1(Packet * pak,UWORD at,UBYTE data)414 void PacketWriteAt1 (Packet *pak, UWORD at, UBYTE data)
415 {
416 assert (pak);
417 assert (at < PacketMaxData);
418
419 pak->data[at++] = data;
420 if (at > pak->len)
421 pak->len = at;
422 }
423
PacketWriteAt2(Packet * pak,UWORD at,UWORD data)424 void PacketWriteAt2 (Packet *pak, UWORD at, UWORD data)
425 {
426 assert (pak);
427 assert (at + 1 < PacketMaxData);
428
429 pak->data[at++] = data & 0xff; data >>= 8;
430 pak->data[at++] = data;
431 if (at > pak->len)
432 pak->len = at;
433 }
434
PacketWriteAtB2(Packet * pak,UWORD at,UWORD data)435 void PacketWriteAtB2 (Packet *pak, UWORD at, UWORD data)
436 {
437 assert (pak);
438 assert (at + 1 < PacketMaxData);
439
440 pak->data[at++] = data >> 8;
441 pak->data[at++] = data & 0xff;
442 if (at > pak->len)
443 pak->len = at;
444 }
445
PacketWriteAt4(Packet * pak,UWORD at,UDWORD data)446 void PacketWriteAt4 (Packet *pak, UWORD at, UDWORD data)
447 {
448 assert (pak);
449 assert (at + 3 < PacketMaxData);
450
451 pak->data[at++] = data & 0xff; data >>= 8;
452 pak->data[at++] = data & 0xff; data >>= 8;
453 pak->data[at++] = data & 0xff; data >>= 8;
454 pak->data[at++] = data;
455 if (at > pak->len)
456 pak->len = at;
457 }
458
PacketWriteAtB4(Packet * pak,UWORD at,UDWORD data)459 void PacketWriteAtB4 (Packet *pak, UWORD at, UDWORD data)
460 {
461 assert (pak);
462 assert (at + 3 < PacketMaxData);
463
464 pak->data[at++] = data >> 24;
465 pak->data[at++] = (data >> 16) & 0xff;
466 pak->data[at++] = (data >> 8) & 0xff;
467 pak->data[at++] = data & 0xff;
468 if (at > pak->len)
469 pak->len = at;
470 }
471
PacketRead1(Packet * pak)472 UBYTE PacketRead1 (Packet *pak)
473 {
474 assert (pak);
475
476 if (pak->rpos + 1 > PacketMaxData)
477 return 0;
478
479 return pak->data[pak->rpos++];
480 }
481
PacketRead2(Packet * pak)482 UWORD PacketRead2 (Packet *pak)
483 {
484 UWORD data;
485
486 assert (pak);
487
488 if (pak->rpos + 2 > PacketMaxData)
489 return 0;
490
491 data = pak->data[pak->rpos++];
492 data |= pak->data[pak->rpos++] << 8;
493 return data;
494 }
495
PacketReadB2(Packet * pak)496 UWORD PacketReadB2 (Packet *pak)
497 {
498 UWORD data;
499
500 assert (pak);
501
502 if (pak->rpos + 2 > PacketMaxData)
503 return 0;
504
505 data = pak->data[pak->rpos++] << 8;
506 data |= pak->data[pak->rpos++];
507 return data;
508 }
509
PacketRead4(Packet * pak)510 UDWORD PacketRead4 (Packet *pak)
511 {
512 UDWORD data;
513
514 assert (pak);
515
516 if (pak->rpos + 4 > PacketMaxData)
517 return 0;
518
519 data = pak->data[pak->rpos++];
520 data |= pak->data[pak->rpos++] << 8;
521 data |= pak->data[pak->rpos++] << 16;
522 data |= pak->data[pak->rpos++] << 24;
523 return data;
524 }
525
PacketReadB4(Packet * pak)526 UDWORD PacketReadB4 (Packet *pak)
527 {
528 UDWORD data;
529
530 assert (pak);
531
532 if (pak->rpos + 4 > PacketMaxData)
533 return 0;
534
535 data = pak->data[pak->rpos++] << 24;
536 data |= pak->data[pak->rpos++] << 16;
537 data |= pak->data[pak->rpos++] << 8;
538 data |= pak->data[pak->rpos++];
539 return data;
540 }
541
PacketReadCap(Packet * pak)542 Cap *PacketReadCap (Packet *pak)
543 {
544 const UBYTE *cap;
545 UBYTE id;
546 char *p;
547
548 assert (pak);
549
550 if (pak->rpos + 16 > PacketMaxData)
551 return &caps[0];
552
553 cap = pak->data + pak->rpos;
554 pak->rpos += 16;
555
556 for (id = 0; id < CAP_MAX; id++)
557 if (caps[id].cap)
558 {
559 #ifdef HAVE_MEMCMP
560 if (!memcmp (cap, caps[id].cap, caps[id].len))
561 {
562 if (caps[id].len != 16)
563 {
564 s_free (caps[id].var);
565 caps[id].var = malloc (16);
566 memcpy (caps[id].var, cap, 16);
567 }
568 return &caps[id];
569 }
570 #else
571 {
572 const UBYTE *p, *q;
573 int i;
574 for (p = cap, q = caps[id].cap, i = 0; i < caps[id].len; i++)
575 if (*p++ != *q++)
576 break;
577 else
578 if (i + 1 == caps[id].len)
579 {
580 if (caps[id].len != 16)
581 {
582 s_free ((char *)caps[id].var);
583 caps[id].var = malloc (16);
584 memcpy (caps[id].var, cap, 16);
585 }
586 return &caps[id];
587 }
588 }
589 #endif
590 }
591 else
592 break;
593 if (id == CAP_MAX)
594 return &caps[0];
595
596 p = malloc (16);
597 assert (p);
598 memcpy (p, cap, 16);
599
600 caps[id].id = id;
601 caps[id].cap = p;
602 caps[id].len = 16;
603 caps[id].name = strdup (s_sprintf ("CAP_UNK_%d", id));
604 return &caps[id];
605 }
606
PacketReadData(Packet * pak,str_t str,UWORD len)607 void PacketReadData (Packet *pak, str_t str, UWORD len)
608 {
609 assert (pak);
610
611 if (pak->rpos + len > PacketMaxData)
612 {
613 if (str)
614 {
615 str->len = 0;
616 if (str->max)
617 *str->txt = '\0';
618 }
619 return;
620 }
621 if (str)
622 {
623 s_init (str, "", len + 1);
624 if (str->max > len)
625 {
626 str->len = len;
627 str->txt[len] = '\0';
628 memcpy (str->txt, pak->data + pak->rpos, len);
629 }
630 }
631 pak->rpos += len;
632 }
633
PacketReadB2Str(Packet * pak,str_t str)634 strc_t PacketReadB2Str (Packet *pak, str_t str)
635 {
636 unsigned int len;
637
638 len = PacketReadB2 (pak);
639 if (pak->rpos + len >= PacketMaxData)
640 {
641 if (!str)
642 return &packetstr[PACKETSTRINVALID];
643 s_init (str, packetstr[PACKETSTRINVALID].txt, 0);
644 return str;
645 }
646
647 if (!str)
648 {
649 packetstrind %= 4;
650 str = &packetstr[packetstrind++];
651 }
652
653 s_init (str, "", len + 2);
654 assert (str->max >= len + 2);
655
656 PacketReadData (pak, str, len);
657 str->txt[str->len = len] = '\0';
658
659 return str;
660 }
661
PacketReadL2Str(Packet * pak,str_t str)662 strc_t PacketReadL2Str (Packet *pak, str_t str)
663 {
664 unsigned int len;
665
666 len = PacketRead2 (pak);
667 if (pak->rpos + len >= PacketMaxData)
668 {
669 if (!str)
670 return &packetstr[PACKETSTRINVALID];
671 s_init (str, packetstr[PACKETSTRINVALID].txt, 0);
672 return str;
673 }
674 if (!len)
675 {
676 if (!str)
677 return &packetstr[PACKETSTREMPTY];
678 s_init (str, "", 0);
679 return str;
680 }
681
682 if (!str)
683 {
684 packetstrind %= 4;
685 str = &packetstr[packetstrind++];
686 }
687
688 s_init (str, "", len + 2);
689 assert (str->max >= len + 2);
690
691 PacketReadData (pak, str, len);
692 if (str->txt[len - 1])
693 str->txt[str->len = len] = '\0';
694 else
695 str->len = len - 1;
696 return str;
697 }
698
PacketReadL4Str(Packet * pak,str_t str)699 strc_t PacketReadL4Str (Packet *pak, str_t str)
700 {
701 size_t len;
702
703 len = PacketRead4 (pak);
704 if (pak->rpos + len >= PacketMaxData)
705 {
706 if (!str)
707 return &packetstr[PACKETSTRINVALID];
708 s_init (str, packetstr[PACKETSTRINVALID].txt, 0);
709 return str;
710 }
711
712 if (!str)
713 {
714 packetstrind %= 4;
715 str = &packetstr[packetstrind++];
716 }
717
718 s_init (str, "", len + 2);
719 assert (str->max >= len + 2);
720
721 PacketReadData (pak, str, len);
722 str->txt[str->len = len] = '\0';
723
724 return str;
725 }
726
PacketReadUIN(Packet * pak)727 strc_t PacketReadUIN (Packet *pak)
728 {
729 UBYTE len = PacketRead1 (pak);
730 str_t str;
731
732 packetstrind %= 4;
733 str = &packetstr[packetstrind++];
734 s_init (str, "", len + 2);
735 PacketReadData (pak, str, len);
736 str->txt[len] = '\0';
737 return str;
738 }
739
PacketReadCont(Packet * pak,Server * serv)740 Contact *PacketReadCont (Packet *pak, Server *serv)
741 {
742 UBYTE len = PacketRead1 (pak);
743 Contact *cont;
744 str_s str = { NULL, 0, 0 };
745
746 PacketReadData (pak, &str, len);
747 str.txt[len] = '\0';
748 cont = ContactScreen (serv, str.txt);
749 s_done (&str);
750 return cont;
751 }
752
PacketReadPos(const Packet * pak)753 UWORD PacketReadPos (const Packet *pak)
754 {
755 return pak->rpos;
756 }
757
PacketReadAt1(const Packet * pak,UWORD at)758 UBYTE PacketReadAt1 (const Packet *pak, UWORD at)
759 {
760 assert (pak);
761
762 if (at + 1 > PacketMaxData)
763 return 0;
764
765 return pak->data[at];
766 }
767
PacketReadAt2(const Packet * pak,UWORD at)768 UWORD PacketReadAt2 (const Packet *pak, UWORD at)
769 {
770 UWORD data;
771
772 assert (pak);
773
774 if (at + 2 > PacketMaxData)
775 return 0;
776
777 data = pak->data[at++];
778 data |= pak->data[at] << 8;
779 return data;
780 }
781
PacketReadAtB2(const Packet * pak,UWORD at)782 UWORD PacketReadAtB2 (const Packet *pak, UWORD at)
783 {
784 UWORD data;
785
786 assert (pak);
787
788 if (at + 2 > PacketMaxData)
789 return 0;
790
791 data = pak->data[at++] << 8;
792 data |= pak->data[at];
793 return data;
794 }
795
PacketReadAt4(const Packet * pak,UWORD at)796 UDWORD PacketReadAt4 (const Packet *pak, UWORD at)
797 {
798 UDWORD data;
799
800 assert (pak);
801
802 if (at + 4 > PacketMaxData)
803 return 0;
804
805 data = pak->data[at++];
806 data |= pak->data[at++] << 8;
807 data |= pak->data[at++] << 16;
808 data |= pak->data[at] << 24;
809 return data;
810 }
811
PacketReadAtB4(const Packet * pak,UWORD at)812 UDWORD PacketReadAtB4 (const Packet *pak, UWORD at)
813 {
814 UDWORD data;
815
816 assert (pak);
817
818 if (at + 4 > PacketMaxData)
819 return 0;
820
821 data = pak->data[at++] << 24;
822 data |= pak->data[at++] << 16;
823 data |= pak->data[at++] << 8;
824 data |= pak->data[at];
825 return data;
826 }
827
PacketReadAtData(const Packet * pak,UWORD at,str_t str,UWORD len)828 void PacketReadAtData (const Packet *pak, UWORD at, str_t str, UWORD len)
829 {
830 assert (pak);
831
832 if (at + len > PacketMaxData)
833 {
834 if (str)
835 {
836 str->len = 0;
837 if (str->max)
838 *str->txt = '\0';
839 }
840 return;
841 }
842 if (str)
843 {
844 s_init (str, "", len + 1);
845 if (str->max > len)
846 memcpy (str->txt, pak->data + at, len);
847 }
848 }
849
PacketReadAtL2Str(const Packet * pak,UWORD at,str_t str)850 strc_t PacketReadAtL2Str (const Packet *pak, UWORD at, str_t str)
851 {
852 unsigned int len;
853
854 len = PacketReadAt2 (pak, at);
855 if (at + 2 + len >= PacketMaxData)
856 {
857 if (!str)
858 return &packetstr[PACKETSTRINVALID];
859 s_init (str, packetstr[PACKETSTRINVALID].txt, 0);
860 return str;
861 }
862 if (!len)
863 {
864 if (!str)
865 return &packetstr[PACKETSTREMPTY];
866 s_init (str, "", 0);
867 return str;
868 }
869
870 if (!str)
871 {
872 packetstrind %= 4;
873 str = &packetstr[packetstrind++];
874 }
875
876 s_init (str, "", len + 2);
877 assert (str->max >= len + 2);
878
879 PacketReadAtData (pak, at + 2, str, len);
880 if (str->txt[len - 1])
881 str->txt[str->len = len] = '\0';
882 else
883 str->len = len - 1;
884
885 return str;
886 }
887
PacketReadLeft(const Packet * pak)888 int PacketReadLeft (const Packet *pak)
889 {
890 if (pak->rpos > pak->len)
891 return 0;
892 return pak->len - pak->rpos;
893 }
894
PacketCap(UBYTE id)895 Cap *PacketCap (UBYTE id)
896 {
897 if (id >= CAP_MAX)
898 return &caps[0];
899 return &caps[id];
900 }
901
902