1 /*
2  * Copyright (C) 1998,1999,2000  Ross Combs (rocombs@cs.nmsu.edu)
3  * Copyright (C) 1999,2000,2001  Marco Ziech (mmz@gmx.net)
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  */
19 #include "common/setup_before.h"
20 #ifdef HAVE_STDDEF_H
21 # include <stddef.h>
22 #else
23 # ifndef NULL
24 #  define NULL ((void *)0)
25 # endif
26 #endif
27 #ifdef STDC_HEADERS
28 # include <stdlib.h>
29 #else
30 # ifdef HAVE_MALLOC_H
31 #  include <malloc.h>
32 # endif
33 #endif
34 #ifdef HAVE_STRING_H
35 # include <string.h>
36 #else
37 # ifdef HAVE_STRINGS_H
38 #  include <strings.h>
39 # endif
40 #endif
41 #ifdef HAVE_MEMORY_H
42 # include <memory.h>
43 #endif
44 #include "compat/memcpy.h"
45 #include "common/eventlog.h"
46 #include "common/bn_type.h"
47 #include "common/field_sizes.h"
48 #include "common/xalloc.h"
49 #include "common/lstr.h"
50 #include "common/packet.h"
51 #include "common/setup_after.h"
52 
53 
packet_create(t_packet_class class)54 extern t_packet * packet_create(t_packet_class class)
55 {
56     t_packet * temp;
57 
58     if (class!=packet_class_init &&
59 	class!=packet_class_bnet &&
60 	class!=packet_class_file &&
61 	class!=packet_class_udp &&
62 	class!=packet_class_raw &&
63 	class!=packet_class_d2game &&
64         class!=packet_class_d2cs &&
65         class!=packet_class_d2gs &&
66 	class!=packet_class_d2cs_bnetd &&
67 	class!=packet_class_w3route)
68     {
69 	eventlog(eventlog_level_error,__FUNCTION__,"invalid packet class %d",(int)class);
70         return NULL;
71     }
72 
73     temp = xmalloc(sizeof(t_packet));
74     temp->ref   = 1;
75     temp->class = class;
76     temp->flags = 0;
77     packet_set_size(temp,0);
78 
79     return temp;
80 }
81 
82 
packet_destroy(t_packet const * packet)83 extern void packet_destroy(t_packet const * packet)
84 {
85     if (!packet)
86     {
87 	eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
88 	return;
89     }
90 
91     xfree((void *)packet); /* avoid warning */
92 }
93 
94 
packet_add_ref(t_packet * packet)95 extern t_packet * packet_add_ref(t_packet * packet)
96 {
97     if (!packet)
98     {
99 	eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
100 	return NULL;
101     }
102 
103     packet->ref++;
104     return packet;
105 }
106 
107 
packet_del_ref(t_packet * packet)108 extern void packet_del_ref(t_packet * packet)
109 {
110     if (!packet)
111     {
112 	eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
113 	return;
114     }
115 
116     if (packet->ref<2) /* if would go to zero */
117 	packet_destroy(packet);
118     else
119 	packet->ref--;
120 }
121 
122 
packet_get_class(t_packet const * packet)123 extern t_packet_class packet_get_class(t_packet const * packet)
124 {
125     if (!packet)
126     {
127 	eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
128 	return packet_class_none;
129     }
130 
131     switch (packet->class)
132     {
133     case packet_class_init:
134 	return packet_class_init;
135     case packet_class_bnet:
136         return packet_class_bnet;
137     case packet_class_file:
138         return packet_class_file;
139     case packet_class_udp:
140 	return packet_class_udp;
141     case packet_class_raw:
142         return packet_class_raw;
143     case packet_class_d2game:
144         return packet_class_d2game;
145     case packet_class_d2cs:
146         return packet_class_d2cs;
147     case packet_class_d2gs:
148         return packet_class_d2gs;
149     case packet_class_d2cs_bnetd:
150         return packet_class_d2cs_bnetd;
151     case packet_class_w3route:
152         return packet_class_w3route;
153     case packet_class_none:
154 	return packet_class_none;
155     default:
156 	eventlog(eventlog_level_error,__FUNCTION__,"packet has invalid class %d",(int)packet->class);
157 	return packet_class_none;
158     }
159 }
160 
161 
packet_get_class_str(t_packet const * packet)162 extern char const * packet_get_class_str(t_packet const * packet)
163 {
164     if (!packet)
165     {
166 	eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
167 	return "unknown";
168     }
169 
170     switch (packet->class)
171     {
172     case packet_class_init:
173         return "init";
174     case packet_class_bnet:
175         return "bnet";
176     case packet_class_file:
177         return "file";
178     case packet_class_udp:
179         return "udp";
180     case packet_class_raw:
181         return "raw";
182     case packet_class_d2game:
183         return "d2game";
184     case packet_class_d2gs:
185         return "d2gs";
186     case packet_class_d2cs_bnetd:
187         return "d2cs_bnetd";
188     case packet_class_d2cs:
189         return "d2cs";
190     case packet_class_w3route:
191 	return "w3route";
192     case packet_class_none:
193 	return "none";
194     default:
195 	eventlog(eventlog_level_error,__FUNCTION__,"packet has invalid class %d",(int)packet->class);
196 	return "unknown";
197     }
198 }
199 
200 
packet_set_class(t_packet * packet,t_packet_class class)201 extern int packet_set_class(t_packet * packet, t_packet_class class)
202 {
203     if (!packet)
204     {
205 	eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
206 	return -1;
207     }
208     if (packet->class!=packet_class_raw)
209     {
210 	eventlog(eventlog_level_error,__FUNCTION__,"got non-raw packet");
211 	return -1;
212     }
213     if (class!=packet_class_init &&
214 	class!=packet_class_bnet &&
215 	class!=packet_class_file &&
216 	class!=packet_class_udp &&
217 	class!=packet_class_raw &&
218 	class!=packet_class_d2game &&
219         class!=packet_class_d2cs &&
220         class!=packet_class_d2gs &&
221         class!=packet_class_d2cs_bnetd &&
222 	class!=packet_class_w3route)
223     {
224 	eventlog(eventlog_level_error,__FUNCTION__,"invalid packet class %d",(int)class);
225         return -1;
226     }
227 
228     packet->class = class;
229     return 0;
230 }
231 
232 
packet_get_type(t_packet const * packet)233 extern unsigned int packet_get_type(t_packet const * packet)
234 {
235     if (!packet)
236     {
237 	eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
238 	return 0;
239     }
240 
241     switch (packet->class)
242     {
243     case packet_class_init:
244 	return CLIENT_INITCONN; /* all init packets are of this type */
245 
246     case packet_class_bnet:
247 	if (packet_get_size(packet)<sizeof(t_bnet_header))
248 	{
249 	    eventlog(eventlog_level_error,__FUNCTION__,"bnet packet is shorter than header (len=%u)",packet_get_size(packet));
250 	    return 0;
251 	}
252 	return (unsigned int)bn_short_get(packet->u.bnet.h.type);
253 
254     case packet_class_file:
255 	if (packet_get_size(packet)<sizeof(t_file_header))
256 	{
257 	    eventlog(eventlog_level_error,__FUNCTION__,"file packet is shorter than header (len=%u)",packet_get_size(packet));
258 	    return 0;
259 	}
260 	return (unsigned int)bn_short_get(packet->u.file.h.type);
261 
262     case packet_class_udp:
263 	if (packet_get_size(packet)<sizeof(t_udp_header))
264 	{
265 	    eventlog(eventlog_level_error,__FUNCTION__,"udp packet is shorter than header (len=%u)",packet_get_size(packet));
266 	    return 0;
267 	}
268 	return bn_int_get(packet->u.udp.h.type);
269 
270     case packet_class_raw:
271 	return 0; /* raw packets don't have a type, but don't warn because the packet dump tries anyway */
272 
273     case packet_class_d2game:
274 	if (packet_get_size(packet)<sizeof(t_d2game_header))
275 	{
276 	    eventlog(eventlog_level_error,__FUNCTION__,"d2game packet is shorter than header (len=%u)",packet_get_size(packet));
277 	    return 0;
278 	}
279 	return bn_byte_get(packet->u.d2game.h.type);
280 
281     case packet_class_d2gs:
282         if (packet_get_size(packet)<sizeof(t_d2cs_d2gs_header))
283         {
284             eventlog(eventlog_level_error,__FUNCTION__,"d2gs packet is shorter than header (len=%u)",packet_get_size(packet));
285             return 0;
286         }
287         return bn_short_get(packet->u.d2cs_d2gs.h.type);
288     case packet_class_d2cs_bnetd:
289         if (packet_get_size(packet)<sizeof(t_d2cs_bnetd_header)) {
290                 eventlog(eventlog_level_error,__FUNCTION__,"d2cs_bnetd packet shorter than header (len=%u)",packet_get_size(packet));
291                 return 0;
292         }
293         return bn_short_get(packet->u.d2cs_d2gs.h.type);
294 
295     case packet_class_d2cs:
296         if (packet_get_size(packet)<sizeof(t_d2cs_client_header))
297         {
298             eventlog(eventlog_level_error,__FUNCTION__,"d2cs packet is shorter than header (len=%u)",packet_get_size(packet));
299             return 0;
300         }
301         return bn_byte_get(packet->u.d2cs_client.h.type);
302 
303     case packet_class_w3route:
304 	if (packet_get_size(packet)<sizeof(t_w3route_header))
305 	{
306 	    eventlog(eventlog_level_error,__FUNCTION__,"w3route packet is shorter than header (len=%u)",packet_get_size(packet));
307 	    return 0;
308 	}
309 	return bn_short_get(packet->u.w3route.h.type);
310 
311 
312     default:
313 	eventlog(eventlog_level_error,__FUNCTION__,"packet has invalid class %d",(int)packet->class);
314 	return 0;
315     }
316 }
317 
318 
packet_get_type_str(t_packet const * packet,t_packet_dir dir)319 extern char const * packet_get_type_str(t_packet const * packet, t_packet_dir dir)
320 {
321     if (!packet)
322     {
323 	eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
324 	return "unknown";
325     }
326 
327     switch (dir)
328     {
329     case packet_dir_from_client:
330 	switch (packet->class)
331 	{
332 	case packet_class_init:
333 	    return "CLIENT_INITCONN";
334 	case packet_class_bnet:
335 	    if (packet_get_size(packet)<sizeof(t_bnet_header))
336 	    {
337 		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
338 		return "unknown";
339 	    }
340 	    switch (bn_short_get(packet->u.bnet.h.type))
341 	    {
342 	    case CLIENT_COMPINFO1:
343 		return "CLIENT_COMPINFO1";
344 	    case CLIENT_COMPINFO2:
345 		return "CLIENT_COMPINFO2";
346 	    case CLIENT_COUNTRYINFO1:
347 		return "CLIENT_COUNTRYINFO1";
348 	    case CLIENT_COUNTRYINFO_109:
349 		return "CLIENT_COUNTRYINFO_109";
350 	    case CLIENT_CREATEACCTREQ1:
351 		return "CLIENT_CREATEACCTREQ1";
352 	    case CLIENT_UNKNOWN_2B:
353 		return "CLIENT_UNKNOWN_2B";
354 	    case CLIENT_PROGIDENT:
355 		return "CLIENT_PROGIDENT";
356 	    case CLIENT_AUTHREQ1:
357 		return "CLIENT_AUTHREQ1";
358 	    case CLIENT_AUTHREQ_109:
359 		return "CLIENT_AUTHREQ_109";
360 	    case CLIENT_REGSNOOPREPLY:
361 		return "CLIENT_REGSNOOPREPLY";
362 	    case CLIENT_ICONREQ:
363 		return "CLIENT_ICONREQ";
364 	    case CLIENT_LADDERSEARCHREQ:
365 		return "CLIENT_LADDERSEARCHREQ";
366 	    case CLIENT_CDKEY:
367 		return "CLIENT_CDKEY";
368 	    case CLIENT_CDKEY2:
369 		return "CLIENT_CDKEY2";
370 	    case CLIENT_CDKEY3:
371 		return "CLIENT_CDKEY3";
372 	    case CLIENT_REALMLISTREQ:
373 		return "CLIENT_REALMLISTREQ";
374 	    case CLIENT_REALMLISTREQ_110:
375 		return "CLIENT_REALMLISTREQ_110";
376 	    case CLIENT_PROFILEREQ:
377 		return "CLIENT_PROFILEREQ";
378 	    case CLIENT_UNKNOWN_37:
379 		return "CLIENT_UNKNOWN_37";
380 	    case CLIENT_UNKNOWN_39:
381 		return "CLIENT_UNKNOWN_39";
382 	    case CLIENT_LOGINREQ2:
383 		return "CLIENT_LOGINREQ2";
384 	    case CLIENT_MOTD_W3:
385 		return "CLIENT_MOTD_W3";
386 	    case CLIENT_LOGINREQ_W3:
387                 return "CLIENT_LOGINREQ_W3";
388 	    case CLIENT_LOGONPROOFREQ:
389                 return "CLIENT_LOGONPROOFREQ";
390 	    case CLIENT_CREATEACCOUNT_W3:
391 		return "CLIENT_CREATEACCOUNT_W3";
392 	    case CLIENT_CHANGEGAMEPORT:
393                 return "CLIENT_CHANGEGAMEPORT";
394             case CLIENT_CREATEACCTREQ2:
395 		return "CLIENT_CREATEACCTREQ2";
396 	    case CLIENT_UDPOK:
397 		return "CLIENT_UDPOK";
398 	    case CLIENT_FILEINFOREQ:
399 		return "CLIENT_FILEINFOREQ";
400 	    case CLIENT_STATSREQ:
401 		return "CLIENT_STATSREQ";
402 	    case CLIENT_LOGINREQ1:
403 		return "CLIENT_LOGINREQ1";
404 	    case CLIENT_CHANGEPASSREQ:
405 		return "CLIENT_CHANGEPASSREQ";
406 	    case CLIENT_PLAYERINFOREQ:
407 		return "CLIENT_PLAYERINFOREQ";
408 	    case CLIENT_PROGIDENT2:
409 		return "CLIENT_PROGIDENT2";
410 	    case CLIENT_JOINCHANNEL:
411 		return "CLIENT_JOINCHANNEL";
412 	    case CLIENT_MESSAGE:
413 		return "CLIENT_MESSAGE";
414 	    case CLIENT_GAMELISTREQ:
415 		return "CLIENT_GAMELISTREQ";
416 	    case CLIENT_STARTGAME1:
417 		return "CLIENT_STARTGAME1";
418 	    case CLIENT_UNKNOWN_1B:
419 		return "CLIENT_UNKNOWN_1B";
420 	    case CLIENT_STARTGAME3:
421 		return "CLIENT_STARTGAME3";
422 	    case CLIENT_STARTGAME4:
423 		return "CLIENT_STARTGAME4";
424 	    case CLIENT_CLOSEGAME:
425 		return "CLIENT_CLOSEGAME";
426 	    case CLIENT_CLOSEGAME2:
427 		return "CLIENT_CLOSEGAME2";
428 	    case CLIENT_LEAVECHANNEL:
429 		return "CLIENT_LEAVECHANNEL";
430 	    case CLIENT_MAPAUTHREQ1:
431 		return "CLIENT_MAPAUTHREQ1";
432 	    case CLIENT_MAPAUTHREQ2:
433 		return "CLIENT_MAPAUTHREQ2";
434 	    case CLIENT_ADREQ:
435 		return "CLIENT_ADREQ";
436 	    case CLIENT_ADACK:
437 		return "CLIENT_ADACK";
438 	    case CLIENT_ADCLICK:
439 		return "CLIENT_ADCLICK";
440 	    case CLIENT_ADCLICK2:
441 		return "CLIENT_ADCLICK2";
442 	    case CLIENT_UNKNOWN_17:
443 		return "CLIENT_UNKNOWN_17";
444 	    case CLIENT_UNKNOWN_24:
445 		return "CLIENT_UNKNOWN_24";
446 	    case CLIENT_LADDERREQ:
447 		return "CLIENT_LADDERREQ";
448 	    case CLIENT_ECHOREPLY:
449 		return "CLIENT_ECHOREPLY";
450 	    case CLIENT_PINGREQ:
451 		return "CLIENT_PINGREQ";
452 	    case CLIENT_GAME_REPORT:
453 		return "CLIENT_GAME_REPORT";
454 	    case CLIENT_JOIN_GAME:
455 		return "CLIENT_JOIN_GAME";
456 	    case CLIENT_STATSUPDATE:
457 		return "CLIENT_STATSUPDATE";
458 	    case CLIENT_REALMJOINREQ_109:
459 		return "CLIENT_REALMJOINREQ_109";
460 	    case CLIENT_CHANGECLIENT:
461 		return "CLIENT_CHANGECLIENT";
462 	    case CLIENT_SETEMAILREPLY:
463 		return "CLIENT_SETEMAILREPLY";
464 	    case CLIENT_GETPASSWORDREQ:
465 		return "CLIENT_GETPASSWORDREQ";
466 	    case CLIENT_CHANGEEMAILREQ:
467 		return "CLIENT_CHANGEEMAILREQ";
468 	    case CLIENT_CRASHDUMP:
469 		return "CLIENT_CRASHDUMP";
470 	    case CLIENT_FINDANONGAME:
471 		return "CLIENT_FINDANONGAME";
472 	    case CLIENT_ARRANGEDTEAM_FRIENDSCREEN:
473 		return "CLIENT_ARRANGEDTEAM_FRIENDSCREEN";
474 	    case CLIENT_ARRANGEDTEAM_INVITE_FRIEND:
475 		return "CLIENT_ARRANGEDTEAM_INVITE_FRIEND";
476 	    case CLIENT_ARRANGEDTEAM_ACCEPT_DECLINE_INVITE:
477 		return "CLIENT_ARRANGEDTEAM_ACCEPT_DECLINE_INVITE";
478 	    case CLIENT_FRIENDSLISTREQ:
479 		return "CLIENT_FRIENDSLISTREQ";
480 	    case CLIENT_FRIENDINFOREQ:
481 		return "CLIENT_FRIENDINFOREQ";
482 	    case CLIENT_CLANINFOREQ:
483 	    	return "CLIENT_CLANINFOREQ";
484 	    }
485 	    return "unknown";
486 
487 	case packet_class_file:
488 	    if (packet_get_size(packet)<sizeof(t_file_header))
489 	    {
490 		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
491 		return "unknown";
492 	    }
493 	    switch (bn_short_get(packet->u.file.h.type))
494 	    {
495 	    case CLIENT_FILE_REQ:
496 		return "CLIENT_FILE_REQ";
497 	    }
498 	    return "unknown";
499 
500 	case packet_class_udp:
501 	    if (packet_get_size(packet)<sizeof(t_udp_header))
502 	    {
503 		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
504 		return "unknown";
505 	    }
506 	    switch (bn_int_get(packet->u.udp.h.type))
507 	    {
508 	    case SERVER_UDPTEST: /* we get these if we send stuff to ourself */
509 		return "SERVER_UDPTEST";
510 	    case CLIENT_UDPPING:
511 		return "CLIENT_UDPPING";
512 	    case CLIENT_SESSIONADDR1:
513 		return "CLIENT_SESSIONADDR1";
514 	    case CLIENT_SESSIONADDR2:
515 		return "CLIENT_SESSIONADDR2";
516 	    }
517 	    return "unknown";
518 
519 	case packet_class_raw:
520 	    return "CLIENT_RAW";
521 
522        case packet_class_d2game:
523 	    if (packet_get_size(packet)<sizeof(t_d2game_header))
524 	    {
525                eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
526                return "unknown";
527 	    }
528 	    switch (bn_byte_get(packet->u.d2game.h.type))
529 	    {
530 	    default:
531 		return "CLIENT_D2GAME";
532 	    }
533 	    return "unknown";
534 
535         case packet_class_d2cs:
536                 return "D2CS";
537         case packet_class_d2gs:
538                 return "D2GS";
539         case packet_class_d2cs_bnetd:
540                 return "D2CS_BNETD";
541 
542 	case packet_class_w3route:
543 	    if (packet_get_size(packet)<sizeof(t_w3route_header))
544 	    {
545 		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
546 		return "unknown";
547 	    }
548 	    switch (bn_short_get(packet->u.bnet.h.type))
549 	    {
550 	    case CLIENT_W3ROUTE_REQ:
551 	        return "CLIENT_W3ROUTE_REQ";
552 	    case CLIENT_W3ROUTE_LOADINGDONE:
553 	        return "CLIENT_W3ROUTE_LOADINGDONE";
554 	    case CLIENT_W3ROUTE_ABORT:
555 	        return "CLIENT_W3ROUTE_ABORT";
556 	    case CLIENT_W3ROUTE_CONNECTED:
557 	        return "CLIENT_W3ROUTE_CONNECTED";
558 	    case CLIENT_W3ROUTE_ECHOREPLY:
559 	        return "CLIENT_W3ROUTE_ECHOREPLY";
560 	    case CLIENT_W3ROUTE_GAMERESULT:
561 	        return "CLIENT_W3ROUTE_GAMERESULT";
562 	    case CLIENT_W3ROUTE_GAMERESULT_W3XP:
563 	        return "CLIENT_W3ROUTE_GAMERESULT_W3XP";
564 	    }
565 	    return "unknown";
566 
567 	case packet_class_none:
568 	    return "unknown";
569 	}
570 
571 	eventlog(eventlog_level_error,__FUNCTION__,"packet has invalid class %d",(int)packet->class);
572 	return "unknown";
573 
574     case packet_dir_from_server:
575 	switch (packet->class)
576 	{
577 	case packet_class_init:
578 	    return "unknown";
579 	case packet_class_bnet:
580 	    if (packet_get_size(packet)<sizeof(t_bnet_header))
581 	    {
582 		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
583 		return "unknown";
584 	    }
585 	    switch (bn_short_get(packet->u.bnet.h.type))
586 	    {
587 	    case SERVER_COMPREPLY:
588 		return "SERVER_COMPREPLY";
589 	    case SERVER_SESSIONKEY1:
590 		return "SERVER_SESSIONKEY1";
591 	    case SERVER_SESSIONKEY2:
592 		return "SERVER_SESSIONKEY2";
593 	    case SERVER_CREATEACCTREPLY1:
594 		return "SERVER_CREATEACCTREPLY1";
595 	    case SERVER_AUTHREQ1:
596 		return "SERVER_AUTHREQ1";
597 	    case SERVER_AUTHREQ_109:
598 		return "SERVER_AUTHREQ_109";
599 	    case SERVER_AUTHREPLY1:
600 		return "SERVER_AUTHREPLY1";
601 	    case SERVER_AUTHREPLY_109:
602 		return "SERVER_AUTHREPLY_109";
603 	    case SERVER_REGSNOOPREQ:
604 		return "SERVER_REGSNOOPREQ";
605 	    case SERVER_ICONREPLY:
606 		return "SERVER_ICONREPLY";
607 	    case SERVER_LADDERSEARCHREPLY:
608 		return "SERVER_LADDERSEARCHREPLY";
609 	    case SERVER_CDKEYREPLY:
610 		return "SERVER_CDKEYREPLY";
611 	    case SERVER_CDKEYREPLY2:
612 		return "SERVER_CDKEYREPLY2";
613 	    case SERVER_CDKEYREPLY3:
614 		return "SERVER_CDKEYREPLY3";
615 	    case SERVER_REALMLISTREPLY:
616 		return "SERVER_REALMLISTREPLY";
617 	    case SERVER_REALMLISTREPLY_110:
618 		return "SERVER_REALMLISTREPLY_110";
619 	    case SERVER_PROFILEREPLY:
620 		return "SERVER_PROFILEREPLY";
621 	    case SERVER_UNKNOWN_37:
622 		return "SERVER_UNKNOWN_37";
623 	    case SERVER_MOTD_W3:
624 		return "SERVER_MOTD_W3";
625 	    case SERVER_LOGINREPLY_W3:
626 		return "SERVER_LOGINREPLY_W3";
627 	    case SERVER_LOGONPROOFREPLY:
628 		return "SERVER_LOGONPROOFREPLY";
629 	    case SERVER_CREATEACCOUNT_W3:
630 		return "SERVER_CREATEACCTREPLY2";
631 	    case SERVER_LOGINREPLY2:
632 		return "SERVER_LOGINREPLY2";
633 	    case SERVER_CREATEACCTREPLY2:
634 		return "SERVER_CREATEACCOUNT_W3";
635 	    case SERVER_FILEINFOREPLY:
636 		return "SERVER_FILEINFOREPLY";
637 	    case SERVER_STATSREPLY:
638 		return "SERVER_STATSREPLY";
639 	    case SERVER_LOGINREPLY1:
640 		return "SERVER_LOGINREPLY1";
641 	    case SERVER_CHANGEPASSACK:
642 		return "SERVER_CHANGEPASSACK";
643 	    case SERVER_PLAYERINFOREPLY:
644 		return "SERVER_PLAYERINFOREPLY";
645 	    case SERVER_CHANNELLIST:
646 		return "SERVER_CHANNELLIST";
647 	    case SERVER_SERVERLIST:
648 		return "SERVER_SERVERLIST";
649 	    case SERVER_MESSAGE:
650 		return "SERVER_MESSAGE";
651 	    case SERVER_GAMELISTREPLY:
652 		return "SERVER_GAMELISTREPLY";
653 	    case SERVER_STARTGAME1_ACK:
654 		return "SERVER_STARTGAME1_ACK";
655 	    case SERVER_STARTGAME3_ACK:
656 		return "SERVER_STARTGAME3_ACK";
657 	    case SERVER_STARTGAME4_ACK:
658 		return "SERVER_STARTGAME4_ACK";
659 	    case SERVER_MAPAUTHREPLY1:
660 		return "SERVER_MAPAUTHREPLY1";
661 	    case SERVER_MAPAUTHREPLY2:
662 		return "SERVER_MAPAUTHREPLY2";
663 	    case SERVER_ADREPLY:
664 		return "SERVER_ADREPLY";
665 	    case SERVER_ADCLICKREPLY2:
666 		return "SERVER_ADCLICKREPLY2";
667 	    case SERVER_LADDERREPLY:
668 		return "SERVER_LADDERREPLY";
669 	    case SERVER_ECHOREQ:
670 		return "SERVER_ECHOREQ";
671 	    case SERVER_PINGREPLY:
672 		return "SERVER_PINGREPLY";
673 	    case SERVER_REALMJOINREPLY_109:
674 		return "SERVER_REALMJOINREPLY_109";
675 	    case SERVER_SETEMAILREQ:
676 		return "SERVER_SETEMAILREQ";
677 	    case SERVER_FINDANONGAME:
678 		return "SERVER_FINDANONGAME";
679 	    case SERVER_ARRANGEDTEAM_FRIENDSCREEN:
680 		return "SERVER_ARRANGEDTEAM_FRIENDSCREEN";
681 	    case SERVER_ARRANGEDTEAM_INVITE_FRIEND_ACK:
682 		return "SERVER_ARRANGEDTEAM_INVITE_FRIEND_ACK";
683 	    case SERVER_ARRANGEDTEAM_SEND_INVITE:
684 		return "SERVER_ARRANGEDTEAM_SEND_INVITE";
685 	    case SERVER_ARRANGEDTEAM_MEMBER_DECLINE:
686 		return "SERVER_ARRANGEDTEAM_MEMBER_DECLINE";
687 	    case SERVER_FRIENDSLISTREPLY:
688 		return "SERVER_FRIENDSLISTREPLY";
689 	    case SERVER_FRIENDINFOREPLY:
690 		return "SERVER_FRIENDINFOREPLY";
691 	    case SERVER_FRIENDADD_ACK:
692 		return "SERVER_FRIENDADD_ACK";
693 	    case SERVER_FRIENDDEL_ACK:
694 		return "SERVER_FRIENDDEL_ACK";
695 	    case SERVER_FRIENDMOVE_ACK:
696 		return "SERVER_FRIENDMOVE_ACK";
697 	    case SERVER_CLANINFOREPLY:
698 	    	return "SERVER_CLANINFO_REPLY";
699 	    }
700 	    return "unknown";
701 
702 	case packet_class_file:
703 	    if (packet_get_size(packet)<sizeof(t_file_header))
704 	    {
705 		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
706 		return "unknown";
707 	    }
708 	    switch (bn_short_get(packet->u.file.h.type))
709 	    {
710 	    case SERVER_FILE_REPLY:
711 		return "SERVER_FILE_REPLY";
712 	    }
713 	    return "unknown";
714 
715 	case packet_class_udp:
716 	    if (packet_get_size(packet)<sizeof(t_udp_header))
717 	    {
718 		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
719 		return "unknown";
720 	    }
721 	    switch (bn_int_get(packet->u.udp.h.type))
722 	    {
723 	    case SERVER_UDPTEST:
724 		return "SERVER_UDPTEST";
725 	    }
726 	    return "unknown";
727 
728 	case packet_class_raw:
729 	    return "SERVER_RAW";
730 
731 	case packet_class_d2game:
732 	    if (packet_get_size(packet)<sizeof(t_d2game_header))
733 	    {
734 		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
735 		return "unknown";
736 	    }
737 	    switch (bn_byte_get(packet->u.d2game.h.type))
738 	    {
739 	    default:
740 		return "SERVER_D2GAME";
741 	    }
742 	    return "unknown";
743 
744         case packet_class_d2cs:
745                 return "D2CS";
746         case packet_class_d2gs:
747                 return "D2GS";
748         case packet_class_d2cs_bnetd:
749                 return "D2CS_BNETD";
750 
751 	case packet_class_w3route:
752 	    if (packet_get_size(packet)<sizeof(t_w3route_header))
753 	    {
754 		eventlog(eventlog_level_error,__FUNCTION__,"packet is shorter than header (len=%u)",packet_get_size(packet));
755 		return "unknown";
756 	    }
757 	    switch (bn_short_get(packet->u.bnet.h.type))
758 	    {
759 	    case SERVER_W3ROUTE_READY:
760 	        return "SERVER_W3ROUTE_READY";
761 	    case SERVER_W3ROUTE_LOADINGACK:
762 	        return "SERVER_W3ROUTE_LOADINGACK";
763 	    case SERVER_W3ROUTE_ECHOREQ:
764 	        return "SERVER_W3ROUTE_ECHOREQ";
765 	    case SERVER_W3ROUTE_ACK:
766 	        return "SERVER_W3ROUTE_ACK";
767 	    case SERVER_W3ROUTE_PLAYERINFO:
768 	        return "SERVER_W3ROUTE_PLAYERINFO";
769 	    case SERVER_W3ROUTE_LEVELINFO:
770 	        return "SERVER_W3ROUTE_LEVELINFO";
771 	    case SERVER_W3ROUTE_STARTGAME1:
772 	        return "SERVER_W3ROUTE_STARTGAME1";
773 	    case SERVER_W3ROUTE_STARTGAME2:
774 	        return "SERVER_W3ROUTE_STARTGAME2";
775 	    }
776 	    return "unknown";
777 	case packet_class_none:
778 	    return "unknown";
779 	}
780 
781 	eventlog(eventlog_level_error,__FUNCTION__,"packet has invalid class %d",(int)packet->class);
782 	return "unknown";
783     }
784 
785     eventlog(eventlog_level_error,__FUNCTION__,"got unknown direction %d",(int)dir);
786     return "unknown";
787 }
788 
789 
packet_set_type(t_packet * packet,unsigned int type)790 extern int packet_set_type(t_packet * packet, unsigned int type)
791 {
792     if (!packet)
793     {
794 	eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
795 	return -1;
796     }
797 
798     switch (packet->class)
799     {
800     case packet_class_init:
801 	if (type!=CLIENT_INITCONN)
802 	{
803 	    eventlog(eventlog_level_error,__FUNCTION__,"init packet type 0x%08x is not valid",type);
804 	    return -1;
805 	}
806 	return 0;
807 
808     case packet_class_bnet:
809 	if (packet_get_size(packet)<sizeof(t_bnet_header))
810 	{
811 	    eventlog(eventlog_level_error,__FUNCTION__,"bnet packet is shorter than header (len=%u)",packet_get_size(packet));
812 	    return -1;
813 	}
814 	if (type>MAX_NORMAL_TYPE)
815 	{
816 	    eventlog(eventlog_level_error,__FUNCTION__,"bnet packet type 0x%08x is too large",type);
817 	    return -1;
818 	}
819 	bn_short_set(&packet->u.bnet.h.type,(unsigned short)type);
820 	return 0;
821 
822     case packet_class_file:
823 	if (packet_get_size(packet)<sizeof(t_file_header))
824 	{
825 	    eventlog(eventlog_level_error,__FUNCTION__,"file packet is shorter than header (len=%u)",packet_get_size(packet));
826 	    return -1;
827 	}
828 	if (type>MAX_FILE_TYPE)
829 	{
830 	    eventlog(eventlog_level_error,__FUNCTION__,"file packet type 0x%08x is too large",type);
831 	    return -1;
832 	}
833 	bn_short_set(&packet->u.file.h.type,(unsigned short)type);
834 	return 0;
835 
836     case packet_class_udp:
837 	if (packet_get_size(packet)<sizeof(t_udp_header))
838 	{
839 	    eventlog(eventlog_level_error,__FUNCTION__,"udp packet is shorter than header (len=%u)",packet_get_size(packet));
840 	    return -1;
841 	}
842 	bn_int_set(&packet->u.udp.h.type,type);
843 	return 0;
844 
845     case packet_class_d2game:
846 	if (packet_get_size(packet)<sizeof(t_d2game_header))
847 	{
848 	    eventlog(eventlog_level_error,__FUNCTION__,"d2game packet is shorter than header (len=%u)",packet_get_size(packet));
849 	    return -1;
850 	}
851 	bn_byte_set(&packet->u.d2game.h.type,type);
852 	return 0;
853 
854     case packet_class_d2gs:
855         if (packet_get_size(packet)<sizeof(t_d2cs_d2gs_header))
856         {
857             eventlog(eventlog_level_error,__FUNCTION__,"d2gs packet is shorter than header (len=%u)",packet_get_size(packet));
858             return -1;
859         }
860         bn_short_set(&packet->u.d2cs_d2gs.h.type,type);
861         return 0;
862 
863     case packet_class_d2cs_bnetd:
864         if (packet_get_size(packet)<sizeof(t_d2cs_bnetd_header))
865         {
866             eventlog(eventlog_level_error,__FUNCTION__,"d2cs_bnetd packet is shorter than header (len=%u)",packet_get_size(packet));
867             return -1;
868         }
869         bn_short_set(&packet->u.d2cs_bnetd.h.type,type);
870         return 0;
871 
872     case packet_class_d2cs:
873         if (packet_get_size(packet)<sizeof(t_d2cs_client_header))
874         {
875             eventlog(eventlog_level_error,__FUNCTION__,"d2cs packet is shorter than header (len=%u)",packet_get_size(packet));
876             return -1;
877         }
878         bn_byte_set(&packet->u.d2cs_client.h.type,type);
879         return 0;
880 
881     case packet_class_w3route:
882 	if (packet_get_size(packet)<sizeof(t_w3route_header))
883 	{
884 	    eventlog(eventlog_level_error,__FUNCTION__,"w3route packet is shorter than header (len=%u)",packet_get_size(packet));
885 	    return -1;
886 	}
887 	bn_short_set(&packet->u.w3route.h.type,(unsigned short)type);
888 	return 0;
889 
890 
891     case packet_class_raw:
892 	eventlog(eventlog_level_error,__FUNCTION__,"can not set packet type for raw packet");
893 	return 0;
894 
895     default:
896 	eventlog(eventlog_level_error,__FUNCTION__,"packet has invalid class %d",(int)packet->class);
897 	return -1;
898     }
899 }
900 
901 
902 /* size of the _complete_ packet, not the amount currently received or sent */
packet_get_size(t_packet const * packet)903 extern unsigned int packet_get_size(t_packet const * packet)
904 {
905     unsigned int size;
906 
907     if (!packet)
908     {
909         eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
910 	return 0;
911     }
912 
913     switch (packet->class)
914     {
915     case packet_class_init:
916         size = sizeof(t_client_initconn);
917 	break;
918     case packet_class_bnet:
919         size = (unsigned int)bn_short_get(packet->u.bnet.h.size);
920 	break;
921     case packet_class_file:
922         size = (unsigned int)bn_short_get(packet->u.file.h.size);
923 	break;
924     case packet_class_udp:
925 	size = packet->len;
926 	break;
927     case packet_class_raw:
928 	size = packet->len;
929 	break;
930     case packet_class_d2game:
931 	size = packet->len; /* FIXME: does header not contain the size? */
932 	break;
933     case packet_class_d2gs:
934         size = (unsigned int)bn_short_get(packet->u.d2cs_d2gs.h.size);
935         break;
936     case packet_class_d2cs_bnetd:
937         size = (unsigned int)bn_short_get(packet->u.d2cs_bnetd.h.size);
938         break;
939     case packet_class_d2cs:
940         size = (unsigned int)bn_short_get(packet->u.d2cs_client.h.size);
941         break;
942     case packet_class_w3route:
943 	size = (unsigned int)bn_short_get(packet->u.w3route.h.size);
944 	break;
945     default:
946 	eventlog(eventlog_level_error,__FUNCTION__,"packet has invalid class %d",(int)packet->class);
947 	return 0;
948     }
949 
950     if (size>MAX_PACKET_SIZE)
951     {
952         eventlog(eventlog_level_error,__FUNCTION__,"packet has bad size %u",size);
953 	return 0;
954     }
955     return size;
956 }
957 
958 
packet_set_size(t_packet * packet,unsigned int size)959 extern int packet_set_size(t_packet * packet, unsigned int size)
960 {
961     if (!packet)
962     {
963         eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
964 	return -1;
965     }
966     if (size>MAX_PACKET_SIZE)
967     {
968         eventlog(eventlog_level_error,__FUNCTION__,"got bad size %u",size);
969 	return -1;
970     }
971 
972     switch (packet->class)
973     {
974     case packet_class_init:
975 	if (size!=0 && size!=sizeof(t_client_initconn))
976 	{
977 	    eventlog(eventlog_level_error,__FUNCTION__,"invalid size %u for init packet",size);
978 	    return -1;
979 	}
980 	packet->len = size;
981         return 0;
982     case packet_class_bnet:
983 	if (size!=0 && size<sizeof(t_bnet_header))
984 	{
985 	    eventlog(eventlog_level_error,__FUNCTION__,"invalid size %u for bnet packet",size);
986 	    return -1;
987 	}
988         bn_short_set(&packet->u.bnet.h.size,size);
989         return 0;
990     case packet_class_file:
991 	if (size!=0 && size<sizeof(t_file_header))
992 	{
993 	    eventlog(eventlog_level_error,__FUNCTION__,"invalid size %u for file packet",size);
994 	    return -1;
995 	}
996         bn_short_set(&packet->u.file.h.size,size);
997         return 0;
998     case packet_class_udp:
999 	if (size!=0 && size<sizeof(t_udp_header))
1000 	{
1001 	    eventlog(eventlog_level_error,__FUNCTION__,"invalid size %u for udp packet",size);
1002 	    return -1;
1003 	}
1004 	packet->len = size;
1005 	return 0;
1006     case packet_class_raw:
1007 	packet->len = size;
1008 	return 0;
1009     case packet_class_d2game:
1010 	packet->len = size; /* FIXME: does header not contain the size? */
1011 	return 0;
1012     case packet_class_d2cs:
1013         bn_short_set(&packet->u.d2cs_client.h.size,size);
1014         return 0;
1015     case packet_class_d2gs:
1016         bn_short_set(&packet->u.d2cs_d2gs.h.size,size);
1017         return 0;
1018     case packet_class_d2cs_bnetd:
1019         bn_short_set(&packet->u.d2cs_bnetd.h.size,size);
1020         return 0;
1021     case packet_class_w3route:
1022 	if (size!=0 && size<sizeof(t_w3route_header))
1023 	{
1024 	    eventlog(eventlog_level_error,__FUNCTION__,"invalid size %u for w3route packet",size);
1025 	    return -1;
1026 	}
1027         bn_short_set(&packet->u.w3route.h.size,size);
1028         return 0;
1029     default:
1030 	eventlog(eventlog_level_error,__FUNCTION__,"packet has invalid class %d",(int)packet->class);
1031 	return -1;
1032     }
1033 }
1034 
1035 
packet_get_header_size(t_packet const * packet)1036 extern unsigned int packet_get_header_size(t_packet const * packet)
1037 {
1038     if (!packet)
1039     {
1040         eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
1041 	return MAX_PACKET_SIZE;
1042     }
1043 
1044     switch (packet_get_class(packet))
1045     {
1046     case packet_class_init:
1047         return 0;
1048     case packet_class_bnet:
1049         return sizeof(t_bnet_header);
1050     case packet_class_file:
1051         return sizeof(t_file_header);
1052     case packet_class_udp:
1053         return sizeof(t_udp_header);
1054     case packet_class_raw:
1055         return 0;
1056     case packet_class_d2game:
1057         return 0; /* FIXME: is there no game packet header? */
1058     case packet_class_d2cs:
1059         return sizeof(t_d2cs_client_header);
1060     case packet_class_d2gs:
1061         return sizeof(t_d2cs_d2gs_header);
1062     case packet_class_d2cs_bnetd:
1063         return sizeof(t_d2cs_bnetd_header);
1064     case packet_class_w3route:
1065         return sizeof(t_w3route_header);
1066     default:
1067         eventlog(eventlog_level_error,__FUNCTION__,"packet has bad class %d",(int)packet_get_class(packet));
1068         return MAX_PACKET_SIZE;
1069     }
1070 }
1071 
1072 
packet_get_flags(t_packet const * packet)1073 extern unsigned int packet_get_flags(t_packet const * packet)
1074 {
1075     if (!packet)
1076     {
1077         eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
1078         return 0;
1079     }
1080 
1081     return packet->flags;
1082 }
1083 
1084 
packet_set_flags(t_packet * packet,unsigned int flags)1085 extern int packet_set_flags(t_packet * packet, unsigned int flags)
1086 {
1087     if (!packet)
1088     {
1089         eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
1090         return -1;
1091     }
1092 
1093     packet->flags = flags;
1094     return 0;
1095 }
1096 
1097 
packet_append_string(t_packet * packet,char const * str)1098 extern int packet_append_string(t_packet * packet, char const * str)
1099 {
1100     unsigned int   len;
1101     unsigned short addlen;
1102     unsigned short size;
1103 
1104     if (!packet)
1105     {
1106         eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
1107         return -1;
1108     }
1109     if (!str)
1110     {
1111         eventlog(eventlog_level_error,__FUNCTION__,"got NULL string");
1112         return -1;
1113     }
1114 
1115     len = strlen(str)+1;
1116     size = packet_get_size(packet);
1117     if (size>=MAX_PACKET_SIZE)
1118         return -1;
1119 
1120     if (MAX_PACKET_SIZE-(unsigned int)size>len)
1121 	    addlen = len;
1122     else
1123 	    addlen = MAX_PACKET_SIZE-size;
1124     if (addlen<1)
1125 	return -1;
1126 
1127     memcpy(packet->u.data+size,str,addlen-1);
1128     packet->u.data[size+addlen-1] = '\0';
1129     packet_set_size(packet,size+addlen);
1130 
1131     return (int)addlen;
1132 }
1133 
1134 
packet_append_ntstring(t_packet * packet,char const * str)1135 extern int packet_append_ntstring(t_packet * packet, char const * str)
1136 {
1137     unsigned int   len;
1138     unsigned short addlen;
1139     unsigned short size;
1140 
1141     if (!packet)
1142     {
1143         eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
1144         return -1;
1145     }
1146     if (!str)
1147     {
1148         eventlog(eventlog_level_error,__FUNCTION__,"got NULL string");
1149         return -1;
1150     }
1151 
1152     len = strlen(str);
1153     size = packet_get_size(packet);
1154     if (size>=MAX_PACKET_SIZE)
1155         return -1;
1156 
1157     if (MAX_PACKET_SIZE-(unsigned int)size>len)
1158 	    addlen = len;
1159     else
1160 	    addlen = MAX_PACKET_SIZE-size;
1161     if (addlen<1)
1162 	return -1;
1163 
1164     memcpy(packet->u.data+size,str,addlen);
1165     packet_set_size(packet,size+addlen);
1166 
1167     return (int)addlen;
1168 }
1169 
1170 
packet_append_lstr(t_packet * packet,t_lstr * lstr)1171 extern int packet_append_lstr(t_packet * packet, t_lstr *lstr)
1172 {
1173     unsigned short addlen;
1174     unsigned short size;
1175 
1176     if (!packet)
1177     {
1178         eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
1179         return -1;
1180     }
1181     if (!lstr || !lstr_get_str(lstr))
1182     {
1183         eventlog(eventlog_level_error,__FUNCTION__,"got NULL string");
1184         return -1;
1185     }
1186 
1187     size = packet_get_size(packet);
1188     if (size>=MAX_PACKET_SIZE)
1189         return -1;
1190 
1191     if (MAX_PACKET_SIZE-(unsigned int)size>lstr_get_len(lstr))
1192 	    addlen = lstr_get_len(lstr);
1193     else
1194 	    addlen = MAX_PACKET_SIZE-size;
1195     if (addlen<1)
1196 	return -1;
1197 
1198     memcpy(packet->u.data+size,lstr_get_str(lstr),addlen-1);
1199     packet->u.data[size+addlen-1] = '\0';
1200     packet_set_size(packet,size+addlen);
1201 
1202     return (int)addlen;
1203 }
1204 
1205 
packet_append_data(t_packet * packet,void const * data,unsigned int len)1206 extern int packet_append_data(t_packet * packet, void const * data, unsigned int len)
1207 {
1208     unsigned short addlen;
1209     unsigned short size;
1210 
1211     if (!packet)
1212     {
1213         eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
1214         return -1;
1215     }
1216     if (!data)
1217     {
1218         eventlog(eventlog_level_error,__FUNCTION__,"got NULL data");
1219         return -1;
1220     }
1221 
1222     size = packet_get_size(packet);
1223     if (size>=MAX_PACKET_SIZE)
1224         return -1;
1225 
1226     if (MAX_PACKET_SIZE-(unsigned int)size>len)
1227 	    addlen = len;
1228     else
1229 	    addlen = MAX_PACKET_SIZE-size;
1230     if (addlen<1)
1231 	return -1;
1232 
1233     memcpy(packet->u.data+size,data,addlen);
1234     packet_set_size(packet,size+addlen);
1235 
1236     return (int)addlen;
1237 }
1238 
1239 
packet_get_raw_data_const(t_packet const * packet,unsigned int offset)1240 extern void const * packet_get_raw_data_const(t_packet const * packet, unsigned int offset)
1241 {
1242     unsigned int size;
1243 
1244     if (!packet)
1245     {
1246         eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
1247         return NULL;
1248     }
1249     size = (unsigned int)packet_get_size(packet);
1250     if (offset>=size || offset>=MAX_PACKET_SIZE)
1251     {
1252         eventlog(eventlog_level_error,__FUNCTION__,"got bad offset %u for packet size %u",offset,size);
1253         return NULL;
1254     }
1255 
1256     return packet->u.data+offset;
1257 }
1258 
1259 
packet_get_raw_data(t_packet * packet,unsigned int offset)1260 extern void * packet_get_raw_data(t_packet * packet, unsigned int offset)
1261 {
1262     unsigned int size;
1263 
1264     if (!packet)
1265     {
1266         eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
1267         return NULL;
1268     }
1269     size = (unsigned int)packet_get_size(packet);
1270     if (offset>=size || offset>=MAX_PACKET_SIZE)
1271     {
1272         eventlog(eventlog_level_error,__FUNCTION__,"got bad offset %u for packet size %u",offset,size);
1273         return NULL;
1274     }
1275 
1276     return packet->u.data+offset;
1277 }
1278 
1279 
packet_get_raw_data_build(t_packet * packet,unsigned int offset)1280 extern void * packet_get_raw_data_build(t_packet * packet, unsigned int offset)
1281 {
1282     if (!packet)
1283     {
1284         eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
1285         return NULL;
1286     }
1287 
1288     if (offset>=MAX_PACKET_SIZE)
1289     {
1290         eventlog(eventlog_level_error,__FUNCTION__,"got bad offset %u for packet",offset);
1291         return NULL;
1292     }
1293 
1294     return packet->u.data+offset;
1295 }
1296 
1297 
1298 /* maxlen includes room for NUL char */
packet_get_str_const(t_packet const * packet,unsigned int offset,unsigned int maxlen)1299 extern char const * packet_get_str_const(t_packet const * packet, unsigned int offset, unsigned int maxlen)
1300 {
1301     unsigned int size;
1302     unsigned int pos;
1303 
1304     if (!packet)
1305     {
1306         eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
1307         return NULL;
1308     }
1309     size = (unsigned int)packet_get_size(packet);
1310     if (offset>=size)
1311     {
1312         eventlog(eventlog_level_error,__FUNCTION__,"got bad offset %u for packet size %u",offset,size);
1313         return NULL;
1314     }
1315 
1316     for (pos=offset; packet->u.data[pos]!='\0'; pos++)
1317 	if (pos>=size || pos-offset>=maxlen)
1318 	    return NULL;
1319     if (pos>=size || pos-offset>=maxlen) /* NUL must be inside too */
1320 	return NULL;
1321     return packet->u.data+offset;
1322 }
1323 
1324 
packet_get_data_const(t_packet const * packet,unsigned int offset,unsigned int len)1325 extern void const * packet_get_data_const(t_packet const * packet, unsigned int offset, unsigned int len)
1326 {
1327     unsigned int size;
1328 
1329     if (!packet)
1330     {
1331         eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
1332         return NULL;
1333     }
1334     if (len<1)
1335     {
1336         eventlog(eventlog_level_error,__FUNCTION__,"got zero length");
1337 	return NULL;
1338     }
1339     size = (unsigned int)packet_get_size(packet);
1340     if (offset+len>size)
1341     {
1342         eventlog(eventlog_level_error,__FUNCTION__,"got bad offset %u and length %u for packet size %u",offset,len,size);
1343         return NULL;
1344     }
1345 
1346     return packet->u.data+offset;
1347 }
1348 
1349 
packet_duplicate(t_packet const * src)1350 extern t_packet * packet_duplicate(t_packet const * src)
1351 {
1352     t_packet * p;
1353 
1354     if (!(p = packet_create(packet_get_class(src))))
1355     {
1356 	eventlog(eventlog_level_error,__FUNCTION__,"could not create packet");
1357 	return NULL;
1358     }
1359     packet_append_data(p,src->u.data,packet_get_size(src));
1360     packet_set_flags(p,packet_get_flags(src));
1361 
1362     return p;
1363 }
1364 
1365