2 // This file is part of the aMule Project.
4 // Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )
5 // Copyright (c) 2002-2008 Merkur ( devs@emule-project.net / http://www.emule-project.net )
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include <zlib.h> // Needed for uLongf
28 #include "Packet.h" // Interface declarations
30 #include <protocol/Protocols.h>
32 #include "MemFile.h" // Needed for CMemFile
33 #include "OtherStructs.h" // Needed for Header_Struct
34 #include "ArchSpecific.h" // Needed for ENDIAN_*
37 CPacket::CPacket(CPacket
&p
)
42 m_bSplitted
= p
.m_bSplitted
;
43 m_bLastSplitted
= p
.m_bLastSplitted
;
44 m_bPacked
= p
.m_bPacked
;
45 m_bFromPF
= p
.m_bFromPF
;
46 memcpy(head
, p
.head
, sizeof head
);
48 if (p
.completebuffer
) {
49 completebuffer
= new byte
[size
+ 10];;
50 pBuffer
= completebuffer
+ sizeof(Header_Struct
);
52 completebuffer
= NULL
;
54 pBuffer
= new byte
[size
];
60 memcpy( pBuffer
, p
.pBuffer
, size
);
63 CPacket::CPacket(uint8 protocol
)
69 m_bLastSplitted
= false;
72 memset(head
, 0, sizeof head
);
74 completebuffer
= NULL
;
78 // only used for receiving packets
79 CPacket::CPacket(byte
* rawHeader
)
81 memset(head
, 0, sizeof head
);
82 Header_Struct
* header
= (Header_Struct
*)rawHeader
;
83 size
= ENDIAN_SWAP_32(header
->packetlength
) - 1;
84 opcode
= header
->command
;
85 prot
= header
->eDonkeyID
;
87 m_bLastSplitted
= false;
91 completebuffer
= NULL
;
95 CPacket::CPacket(const CMemFile
& datafile
, uint8 protocol
, uint8 ucOpcode
)
97 size
= datafile
.GetLength();
101 m_bLastSplitted
= false;
104 memset(head
, 0, sizeof head
);
106 completebuffer
= new byte
[size
+ sizeof(Header_Struct
)/*Why this 4?*/];
107 pBuffer
= completebuffer
+ sizeof(Header_Struct
);
109 // Write contents of MemFile to buffer (while keeping original position in file)
110 off_t position
= datafile
.GetPosition();
111 datafile
.Seek(0, wxFromStart
);
112 datafile
.Read(pBuffer
, size
);
113 datafile
.Seek(position
, wxFromStart
);
116 CPacket::CPacket(int8 in_opcode
, uint32 in_size
, uint8 protocol
, bool bFromPF
)
122 m_bLastSplitted
= false;
125 memset(head
, 0, sizeof head
);
128 completebuffer
= new byte
[in_size
+ sizeof(Header_Struct
) + 4 /*Why this 4?*/];
129 pBuffer
= completebuffer
+ sizeof(Header_Struct
);
130 memset(completebuffer
, 0, in_size
+ sizeof(Header_Struct
) + 4 /*Why this 4?*/);
132 completebuffer
= NULL
;
137 // only used for splitted packets!
138 CPacket::CPacket(byte
* pPacketPart
, uint32 nSize
, bool bLast
, bool bFromPF
)
140 size
= nSize
- sizeof(Header_Struct
);
144 m_bLastSplitted
= bLast
;
147 memset(head
, 0, sizeof head
);
149 completebuffer
= pPacketPart
;
155 // Never deletes pBuffer when completebuffer is not NULL
156 if (completebuffer
) {
157 delete [] completebuffer
;
158 } else if (pBuffer
) {
159 // On the other hand, if completebuffer is NULL and pBuffer is not NULL
164 delete [] tempbuffer
;
168 void CPacket::AllocDataBuffer(void)
170 wxASSERT(completebuffer
== NULL
);
171 pBuffer
= new byte
[size
+ 1];
174 void CPacket::CopyToDataBuffer(unsigned int offset
, const byte
* data
, unsigned int n
)
176 wxASSERT(offset
+ n
<= size
+ 1);
177 memcpy(pBuffer
+ offset
, data
, n
);
180 byte
* CPacket::GetPacket() {
181 if (completebuffer
) {
183 memcpy(completebuffer
, GetHeader(), sizeof(Header_Struct
));
185 return completebuffer
;
188 delete [] tempbuffer
;
191 tempbuffer
= new byte
[size
+ sizeof(Header_Struct
) + 4 /* why this 4?*/];
192 memcpy(tempbuffer
, GetHeader(), sizeof(Header_Struct
));
193 memcpy(tempbuffer
+ sizeof(Header_Struct
), pBuffer
, size
);
198 byte
* CPacket::DetachPacket() {
199 if (completebuffer
) {
201 memcpy(completebuffer
, GetHeader(), sizeof(Header_Struct
));
203 byte
* result
= completebuffer
;
204 completebuffer
= pBuffer
= NULL
;
211 tempbuffer
= new byte
[size
+sizeof(Header_Struct
)+4 /* Why this 4?*/];
212 memcpy(tempbuffer
,GetHeader(),sizeof(Header_Struct
));
213 memcpy(tempbuffer
+sizeof(Header_Struct
),pBuffer
,size
);
214 byte
* result
= tempbuffer
;
220 byte
* CPacket::GetHeader() {
221 wxASSERT( !m_bSplitted
);
223 Header_Struct
* header
= (Header_Struct
*) head
;
224 header
->command
= opcode
;
225 header
->eDonkeyID
= prot
;
226 header
->packetlength
= ENDIAN_SWAP_32(size
+ 1);
231 byte
* CPacket::GetUDPHeader() {
232 wxASSERT( !m_bSplitted
);
235 UDP_Header_Struct
* header
= (UDP_Header_Struct
*) head
;
236 header
->eDonkeyID
= prot
;
237 header
->command
= opcode
;
243 void CPacket::PackPacket()
245 wxASSERT(!m_bSplitted
);
247 uLongf newsize
= size
+ 300;
248 byte
* output
= new byte
[newsize
];
250 uint16 result
= compress2(output
, &newsize
, pBuffer
, size
, Z_BEST_COMPRESSION
);
252 if (result
!= Z_OK
|| size
<= newsize
) {
257 if (prot
== OP_KADEMLIAHEADER
) {
258 prot
= OP_KADEMLIAPACKEDPROT
;
260 prot
= OP_PACKEDPROT
;
263 memcpy(pBuffer
, output
, newsize
);
271 bool CPacket::UnPackPacket(uint32 uMaxDecompressedSize
) {
272 wxASSERT( prot
== OP_PACKEDPROT
);
274 uint32 nNewSize
= size
* 10 + 300;
276 if (nNewSize
> uMaxDecompressedSize
){
277 nNewSize
= uMaxDecompressedSize
;
280 byte
* unpack
= new byte
[nNewSize
];
281 uLongf unpackedsize
= nNewSize
;
282 uint16 result
= uncompress(unpack
, &unpackedsize
, pBuffer
, size
);
284 if (result
== Z_OK
) {
285 wxASSERT( completebuffer
== NULL
);
286 wxASSERT( pBuffer
!= NULL
);
300 void CPacket::Copy16ToDataBuffer(const void* data
)
302 md4cpy(pBuffer
, data
);
306 void CPacket::CopyUInt32ToDataBuffer(uint32 data
, unsigned int offset
)
308 wxCHECK_RET(offset
<= size
- sizeof(uint32
), wxT("Bad offset in CopyUInt32ToDataBuffer."));
309 PokeUInt32( pBuffer
+ offset
, data
);
311 // File_checked_for_headers