std::ostream& pw::ApnsResponsePacket::write (std::ostream& os) const { char b[getPacketSize()]; this->_write(b); return os.write(b, getPacketSize()); }
ssize_t pw::ApnsResponsePacket::write (IoBuffer& obuf) const { IoBuffer::blob_type b; if ( not obuf.grabWrite(b, getPacketSize()) ) return ssize_t(-1); this->_write(b.buf); obuf.moveWrite(getPacketSize()); return getPacketSize(); }
Packet *newPacketIHAVE(Packet *pktWHOHAS) { uint8_t numHash = getPacketNumHash(pktWHOHAS); int i = 0; int idx; uint8_t *hash; Packet *thisObj = newPacketDefault(); incPacketSize(thisObj, 4); setPacketType(thisObj, "IHAVE"); for(i = 0; i < numHash; i++) { hash = getPacketHash(pktWHOHAS, i); idx = searchHash(hash, &hasChunk, -1); if(idx >= 0) { printf("Has[%d]", i); insertPacketHash(thisObj, hash); } } if(i == 0 || getPacketSize(thisObj) == 20) { freePacket(thisObj); return NULL; } else { setPacketDest(thisObj, &(pktWHOHAS->src), sizeof(pktWHOHAS->src)); return thisObj; } }
std::string& pw::ApnsPacket::write (std::string& ostr) const { ostr.resize(getPacketSize()); this->_write(const_cast<char*>(ostr.c_str()), ostr.size()); return ostr; }
std::ostream& pw::ApnsPacket::write (std::ostream& os) const { blob_type b; b.allocate(getPacketSize()); this->_write(const_cast<char*>(b.buf), b.size); return os.write(b.buf, b.size); }
void flushQueue(int sock, queue *sendQueue) { int i = 0; int retVal = -1; int count = sendQueue->size; int noLoss = 0; Packet *pkt = dequeue(sendQueue); if(pkt == NULL) { return; } peerList_t *list = peerInfo.peerList; while(count > 0) { if(pkt->dest != NULL) { // IHAVE retVal = spiffy_sendto(sock, pkt->payload, getPacketSize(pkt), 0, (struct sockaddr *) (pkt->dest), sizeof(*(pkt->dest))); } else { // WHOHAS for(i = 0; i < peerInfo.numPeer; i++) { if(list[i].isMe == 0) { retVal = spiffy_sendto(sock, pkt->payload, getPacketSize(pkt), 0, (struct sockaddr *) & (list[i].addr), sizeof(list[i].addr)); if(retVal == -1) { enqueue(sendQueue, pkt); noLoss = 1; } } } } if(noLoss == 0) { fprintf(stderr,"spiffy_sendto() returned -1. This is broken!"); } freePacket(pkt); pkt = dequeue(sendQueue); count--; } }
int send_UDP_packet(neightbor_entry *conf, packet p) { if (conf->nodeID == nodeID) return EXIT_SUCCESS; if (sendto(routed_sock, &p, getPacketSize(p), 0, (struct sockaddr *) &conf->saddr, sizeof(conf->saddr)) == -1) { fprintf(stderr, "Failed sending the message.\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; }
void flushUpload(int sock) { int i = 0; Packet *pkt; connUp *pool = uploadPool; for(i = 0; i < peerInfo.numPeer; i++) { int peerID = peerInfo.peerList[i].peerID; Packet *ack = peek(pool[peerID].ackWaitQueue); if(ack != NULL) { struct timeval curTime; gettimeofday(&curTime, NULL); long dt = diffTimeval(&curTime, &(ack->timestamp)); if(dt > DATA_TIMEOUT_SEC) { pool[peerID].timeoutCount++; fprintf(stderr,"Timeout while waiting ACK %d\n", getPacketSeq(ack)); if(pool[peerID].timeoutCount == 3) { fprintf(stderr,"Receiver ID %d timed out 3 times. Closing connection!\n", peerID); numConnUp--; cleanUpConnUp(&(pool[peerID])); continue; } fprintf(stderr,"Data timed out. Resizing window.\n"); shrinkWindow(&(pool[peerID].sw.ctrl)); mergeAtFront(pool[peerID].ackWaitQueue, pool[peerID].dataQueue); } } pkt = peek(pool[peerID].dataQueue); while(pkt != NULL && (getPacketSeq(pkt) <= pool[peerID].sw.lastPacketAvailable)) { peerList_t *p = &(peerInfo.peerList[i]); int retVal = spiffy_sendto(sock, pkt->payload, getPacketSize(pkt), 0, (struct sockaddr *) & (p->addr), sizeof(p->addr)); setPacketTime(pkt); fprintf(stderr,"Sent data %d. last available %d\n", getPacketSeq(pkt), pool[peerID].sw.lastPacketAvailable); if(retVal == -1) { // If spiffy_sendto doesn't f*****g work (AND IT DOESN'T!) fprintf(stderr,"spiffy_sendto() returned -1.\n"); enqueue(pool[peerID].dataQueue, dequeue(pool[peerID].dataQueue)); } else { dequeue(pool[peerID].dataQueue); pool[peerID].sw.lastPacketSent = getPacketSeq(pkt); enqueue(pool[peerID].ackWaitQueue, pkt); pkt = peek(pool[peerID].dataQueue); } } } }
int updateGetSingleChunk(Packet *pkt, int peerID) { recvWindow *rw = &(downloadPool[peerID].rw); int dataSize = getPacketSize(pkt) - 16; uint8_t *dataPtr = pkt->payload + 16; uint32_t seq = (uint32_t)getPacketSeq(pkt); downloadPool[peerID].timeoutCount = 0; fprintf(stderr,"Got pkt %d expecting %d\n", seq, rw->nextPacketExpected); if(seq >= rw->nextPacketExpected) { if((seq > rw->nextPacketExpected) && ((seq - rw->nextPacketExpected) <= INIT_THRESH)) { insertInOrder(&(downloadPool[peerID].cache), newFreePacketACK(seq), seq); newPacketACK(rw->nextPacketExpected - 1, downloadPool[peerID].ackSendQueue); } else if(seq - rw->nextPacketExpected <= INIT_THRESH) { newPacketACK(seq, downloadPool[peerID].ackSendQueue); rw->nextPacketExpected = flushCache(rw->nextPacketExpected, downloadPool[peerID].ackSendQueue, &(downloadPool[peerID].cache)); } rw->lastPacketRead = seq; rw->lastPacketRcvd = seq; int curChunk = downloadPool[peerID].curChunkID; long offset = (seq - 1) * PACKET_DATA_SIZE + BT_CHUNK_SIZE * curChunk; FILE *of = getChunk.filePtr; fprintf(stderr,"In: %d [%ld-%ld]\n", seq, offset, offset + dataSize); if(of != NULL) { fseek(of, offset, SEEK_SET); fwrite(dataPtr, sizeof(uint8_t), dataSize, of); } if(rw->nextPacketExpected > BT_CHUNK_SIZE / PACKET_DATA_SIZE + 1){ clearQueue(downloadPool[peerID].timeoutQueue); fprintf(stderr,"Chunk finished downloading! Next expected %d thresh %d\n", rw->nextPacketExpected, BT_CHUNK_SIZE / PACKET_DATA_SIZE + 1); getChunk.list[curChunk].fetchState = 1; downloadPool[peerID].state = 0; clearQueue(downloadPool[peerID].timeoutQueue); initWindows(&(downloadPool[peerID].rw), &(uploadPool[peerID].sw)); fprintf(stderr,"Chunk %d fetched!\n", curChunk); // fprintf(stderr,"%d More GETs in queue\n", downloadPool[peerID].getQueue->size); return 1; } else { return 0; } } else { fprintf(stderr,"Received an unexpected packet!" "Expecting %d but received %d!", rw->nextPacketExpected, seq); newPacketACK(seq, downloadPool[peerID].ackSendQueue); return 0; } }
bool Packet::decodeBlowfish( bool bUseStaticBFKey ) { int blen = (int)getPacketSize(); int datalen = blen - 2; int n8bc = datalen / 8; int rest = datalen - n8bc*8; if( rest > 0 ) rest = 8; int newdatalen = datalen + rest; int newbuflen = newdatalen + 2; if( blen < 1 ) return false; unsigned char *buf = b.getBytesPtr(); if( !buf ) return false; BF_KEY bfkey; if( bUseStaticBFKey ) BF_set_key( &bfkey, (int)this->STATIC_BLOWFISH_KEY_LEN, this->STATIC_BLOWFISH_KEY ); else BF_set_key( &bfkey, (int)this->NEW_BLOWFISH_KEY_LEN, this->NEW_BLOWFISH_KEY ); int offset = 0; int nPasses = 0; unsigned char outbuf [1024]; /* if( !outbuf ) { return false; } */ memset( outbuf, 0, newbuflen ); outbuf[0] = buf[0]; outbuf[1] = buf[1]; nPasses = 0; for( offset=2; offset<newdatalen; offset+=8 ) { unsigned char data[8] = {0,0,0,0,0,0,0,0}; memcpy( data, buf+offset, 8 ); BF_decrypt( (BF_LONG *)data, &bfkey ); memcpy( outbuf+offset, data, 8 ); nPasses++; } this->setBytes( outbuf, blen ); return true; }
bool L2LoginPacket::padPacketTo8ByteLen() { unsigned char *packet = b.getBytesPtr(); unsigned int plen = getPacketSize(); if( !packet || plen<3 ) return false; unsigned int datalen = plen-2; #ifdef L2LOGINP_DEBUGOUT_PADDING printf( "L2LoginPacket::padPacketTo8ByteLen(): len = %u (data len = %d)\n", plen, datalen ); #endif // L2LOGINP_DEBUGOUT_PADDING unsigned int rest = datalen % 8; unsigned int addsize = 0; if( rest > 0 ) addsize = 8 - rest; #ifdef L2LOGINP_DEBUGOUT_PADDING printf( "L2LoginPacket::padPacketTo8ByteLen(): We should add %u bytes (rest is %u)\n", addsize, rest ); #endif // L2LOGINP_DEBUGOUT_PADDING // save packet len bytes //unsigned char plenbytes[2] = {0,0}; //plenbytes[0] = b.getByteAt( 0 ); //plenbytes[1] = b.getByteAt( 1 ); // append by NULLs if we must append something if( addsize > 0 ) { unsigned int i; for( i=0; i<addsize; i++ ) this->writeUChar( 0x00 ); // restore plen bytes //b.setByteAt( 0, plenbytes[0] ); //b.setByteAt( 1, plenbytes[1] ); #ifdef L2LOGINP_DEBUGOUT_PADDING printf( "L2LoginPacket::padPacketTo8ByteLen(): " "after padding real_size = [%u] ==== \n", this->real_size ); //this->dumpToFile( stdout ); #endif // L2LOGINP_DEBUGOUT_PADDING } return true; }
bool Packet::padPacketTo8ByteLen() { unsigned char *packet = b.getBytesPtr(); unsigned int plen = getPacketSize(); if( !packet || plen<3 ) return false; unsigned int datalen = plen-2; unsigned int rest = datalen % 8; unsigned int addsize = 0; if( rest > 0 ) addsize = 8 - rest; if( addsize > 0 ) { unsigned int i; for( i=0; i<addsize; i++ ) this->writeUChar( 0x00 ); } return true; }
bool Packet::encodeBlowfish( bool bUseStaticBFKey ) { unsigned char *buf = this->b.getBytesPtr(); if( !buf ) return false; unsigned int blen = getPacketSize(); if( blen < 1 ) return false; BF_KEY bfkey; if( bUseStaticBFKey ) BF_set_key( &bfkey, (int)this->STATIC_BLOWFISH_KEY_LEN, this->STATIC_BLOWFISH_KEY ); else BF_set_key( &bfkey, (int)this->NEW_BLOWFISH_KEY_LEN, this->NEW_BLOWFISH_KEY ); unsigned int offset = 0; int nPasses = 0; unsigned char outbuf [1024]; /* if( !outbuf ) { return false; } */ memset( outbuf, 0, blen ); outbuf[0] = buf[0]; outbuf[1] = buf[1]; for( offset=2; offset<real_size-2; offset+=8 ) { unsigned char data[8] = {0,0,0,0,0,0,0,0}; memcpy( data, buf+offset, 8 ); BF_encrypt( (BF_LONG *)data, &bfkey ); memcpy( outbuf+offset, data, 8 ); nPasses++; } this->setBytes( outbuf, blen ); return true; }
int MtpFfsCompatHandle::sendFile(mtp_file_range mfr) { uint64_t file_length = mfr.length; uint32_t given_length = std::min(static_cast<uint64_t>(MAX_MTP_FILE_SIZE), file_length + sizeof(mtp_data_header)); uint64_t offset = mfr.offset; int packet_size = getPacketSize(mBulkIn); // If file_length is larger than a size_t, truncating would produce the wrong comparison. // Instead, promote the left side to 64 bits, then truncate the small result. int init_read_len = std::min( static_cast<uint64_t>(packet_size - sizeof(mtp_data_header)), file_length); unsigned char *data = mIobuf[0].bufs.data(); unsigned char *data2 = mIobuf[1].bufs.data(); posix_fadvise(mfr.fd, 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE); struct aiocb aio; aio.aio_fildes = mfr.fd; struct aiocb *aiol[] = {&aio}; int ret, length; int error = 0; bool read = false; bool write = false; // Send the header data mtp_data_header *header = reinterpret_cast<mtp_data_header*>(data); header->length = htole32(given_length); header->type = htole16(2); /* data packet */ header->command = htole16(mfr.command); header->transaction_id = htole32(mfr.transaction_id); // Some hosts don't support header/data separation even though MTP allows it // Handle by filling first packet with initial file data if (TEMP_FAILURE_RETRY(pread(mfr.fd, reinterpret_cast<char*>(data) + sizeof(mtp_data_header), init_read_len, offset)) != init_read_len) return -1; if (writeHandle(mBulkIn, data, sizeof(mtp_data_header) + init_read_len) == -1) return -1; file_length -= init_read_len; offset += init_read_len; ret = init_read_len + sizeof(mtp_data_header); // Break down the file into pieces that fit in buffers while (file_length > 0) { if (read) { // Wait for the previous read to finish aio_suspend(aiol, 1, nullptr); ret = aio_return(&aio); if (ret == -1) { errno = aio_error(&aio); return -1; } if (static_cast<size_t>(ret) < aio.aio_nbytes) { errno = EIO; return -1; } file_length -= ret; offset += ret; std::swap(data, data2); read = false; write = true; } if (error == -1) { return -1; } if (file_length > 0) { length = std::min(static_cast<uint64_t>(MAX_FILE_CHUNK_SIZE), file_length); // Queue up another read aio_prepare(&aio, data, length, offset); aio_read(&aio); read = true; } if (write) { if (writeHandle(mBulkIn, data2, ret) == -1) { error = -1; } write = false; } } if (ret % packet_size == 0) { // If the last packet wasn't short, send a final empty packet if (TEMP_FAILURE_RETRY(::write(mBulkIn, data, 0)) != 0) { return -1; } } return 0; }
int MtpFfsCompatHandle::receiveFile(mtp_file_range mfr, bool zero_packet) { // When receiving files, the incoming length is given in 32 bits. // A >4G file is given as 0xFFFFFFFF uint32_t file_length = mfr.length; uint64_t offset = mfr.offset; int packet_size = getPacketSize(mBulkOut); unsigned char *data = mIobuf[0].bufs.data(); unsigned char *data2 = mIobuf[1].bufs.data(); struct aiocb aio; aio.aio_fildes = mfr.fd; aio.aio_buf = nullptr; struct aiocb *aiol[] = {&aio}; int ret = -1; size_t length; bool read = false; bool write = false; posix_fadvise(mfr.fd, 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE); // Break down the file into pieces that fit in buffers while (file_length > 0 || write) { if (file_length > 0) { length = std::min(static_cast<uint32_t>(MAX_FILE_CHUNK_SIZE), file_length); // Read data from USB, handle errors after waiting for write thread. ret = readHandle(mBulkOut, data, length); if (file_length != MAX_MTP_FILE_SIZE && ret < static_cast<int>(length)) { ret = -1; errno = EIO; } read = true; } if (write) { // get the return status of the last write request aio_suspend(aiol, 1, nullptr); int written = aio_return(&aio); if (written == -1) { errno = aio_error(&aio); return -1; } if (static_cast<size_t>(written) < aio.aio_nbytes) { errno = EIO; return -1; } write = false; } // If there was an error reading above if (ret == -1) { return -1; } if (read) { if (file_length == MAX_MTP_FILE_SIZE) { // For larger files, receive until a short packet is received. if (static_cast<size_t>(ret) < length) { file_length = 0; } } else { file_length -= ret; } // Enqueue a new write request aio_prepare(&aio, data, length, offset); aio_write(&aio); offset += ret; std::swap(data, data2); write = true; read = false; } } // Receive an empty packet if size is a multiple of the endpoint size. if (ret % packet_size == 0 || zero_packet) { if (TEMP_FAILURE_RETRY(::read(mBulkOut, data, packet_size)) != 0) { return -1; } } return 0; }
void flushDownload(int sock) { int i = 0; int idx; uint8_t *hash; Packet *pkt; connDown *pool = downloadPool; for(i = 0; i < peerInfo.numPeer; i++) { int peerID = peerInfo.peerList[i].peerID; Packet *ack = peek(pool[peerID].ackSendQueue); while(ack != NULL) { peerList_t *p = &(peerInfo.peerList[i]); fprintf(stderr,"Sending ACK %d\n", getPacketAck(ack)); int retVal = spiffy_sendto(sock, ack->payload, getPacketSize(ack), 0, (struct sockaddr *) & (p->addr), sizeof(p->addr)); fprintf(stderr,"Sent ACK %d\n", getPacketAck(ack)); if(retVal == -1) { // spiffy_sendto() does not work!! fprintf(stderr,"spiffy_sendto() returned -1.\n"); enqueue(pool[peerID].ackSendQueue, dequeue(pool[peerID].ackSendQueue)); } else { dequeue(pool[peerID].ackSendQueue); freePacket(ack); ack = dequeue(pool[peerID].ackSendQueue); } } switch(pool[peerID].state) { case 0: // Ready pkt = dequeue(pool[peerID].getQueue); while(pkt != NULL) { hash = getPacketHash(pkt, 0); printHash(hash); idx = searchHash(hash, &getChunk, 0); if(idx == -1) { // Someone else is sending or has sent this chunk freePacket(pkt); pkt = dequeue(pool[peerID].getQueue); } else if(numConnDown < maxConn){ getChunk.list[idx].fetchState = 2; if(downloadPool[peerID].connected == 1) fprintf(stderr,"NOT SUPPOSED TO BE CONNECTEED! \n\n\n\n\n\n"); downloadPool[peerID].connected = 1; numConnDown++; break; } else { // Cannot allow more download connections fprintf(stderr,"->No more download connection allowed!\n"); pool[peerID].state = 2; break; } } if(pool[peerID].state == 2) break; if(pkt != NULL) { fprintf(stderr,"Sending a GET\n"); peerList_t *p = &(peerInfo.peerList[i]); hash = pkt->payload + 16; char buf[50]; bzero(buf, 50); binary2hex(hash, 20, buf); fprintf(stderr,"GET hash:%s\n", buf); pool[peerID].curChunkID = searchHash(hash, &getChunk, -1); int retVal = spiffy_sendto(sock, pkt->payload, getPacketSize(pkt), 0, (struct sockaddr *) & (p->addr), sizeof(p->addr)); if(retVal == -1) { // Spiffy is broken! fprintf(stderr,"spiffy_snetto() returned -1.\n"); newPacketWHOHAS(nonCongestQueue); freePacket(pkt); cleanUpConnDown(&(pool[peerID])); numConnDown--; return; } setPacketTime(pkt); enqueue(pool[peerID].timeoutQueue, pkt); pool[peerID].state = 1; } break; case 1: { // Downloading pkt = peek(pool[peerID].timeoutQueue); struct timeval curTime; gettimeofday(&curTime, NULL); long dt = diffTimeval(&curTime, &(pkt->timestamp)); if(dt > GET_TIMEOUT_SEC) { pool[peerID].timeoutCount++; fprintf(stderr,"GET request timed out %d times!\n", pool[peerID].timeoutCount); setPacketTime(pkt); if(pool[peerID].timeoutCount == 3) { getChunk.list[pool[peerID].curChunkID].fetchState = 0; pool[peerID].state = 0; newPacketWHOHAS(nonCongestQueue); freePacket(pkt); cleanUpConnDown(&(pool[peerID])); numConnDown--; } } break; } case 2: { break; } default: break; } } }
//--------------------------------------------------------------------------- int32_t PacketFile::insertPacket(int32_t packet, puint8_t buffer, int32_t nbytes, uint8_t pType) { //-------------------------------------------------------- // This function writes the packet to the current end // of file and stores the packet address in the seek // table. Originally, replace was a NONO. No, we check // for the size and, if it is different, insert the new // packet into a new file and basically spend many timeparts doing it. // Necessary for the teditor. // I Love it. int32_t result = 0; if(packet < 0) { return result; } //--------------------------------------------------------------- // Only used here, so OK if regular WINDOWS(tm) malloc! puint8_t workBuffer = (puint8_t)malloc(DEFAULT_MAX_PACKET); //------------------------------------------------------------- // All new code here. Basically, open a new packet file, // write each of the old packets and this new one. Close all // and copy the new one over the old one. Open the new one and // set pointers accordingly. PacketFile tmpFile; result = tmpFile.create("AF3456AF.788"); if(packet >= numPackets) { numPackets++; } tmpFile.reserve(numPackets); for(size_t i = 0; i < numPackets; i++) { if(i == packet) { if(nbytes >= DEFAULT_MAX_PACKET) { //---------------------------------------------------- // Not sure what to do here. We'll try reallocating ::free(workBuffer); workBuffer = (puint8_t)malloc(packetSize); } tmpFile.writePacket(i, buffer, nbytes, pType); } else { seekPacket(i); int32_t storageType = getStorageType(); int32_t packetSize = getPacketSize(); if(packetSize >= DEFAULT_MAX_PACKET) { //---------------------------------------------------- // Not sure what to do here. We'll try reallocating ::free(workBuffer); workBuffer = (puint8_t)malloc(packetSize); } readPacket(i, workBuffer); tmpFile.writePacket(i, workBuffer, packetSize, storageType); } } //------------------------------------ // Now close and reassign everything. char ourFileName[250]; int32_t ourFileMode = 0; strcpy(ourFileName, fileName); ourFileMode = fileMode; tmpFile.close(); close(); remove(ourFileName); rename("AF3456AF.788", ourFileName); remove("AF3456AF.788"); open(ourFileName, (FileMode)ourFileMode); seekPacket(packet); return result; }
bool L2LoginPacket::decodeBlowfish( bool bUseStaticBFKey ) { int blen = (int)getPacketSize(); // all array length int datalen = blen - 2; // only data len, w/o 1st 2 bytes - packet size int n8bc = datalen / 8; // 8-byte blocks count int rest = datalen - n8bc*8; // bytes left if( rest > 0 ) rest = 8; // do we need addition? int newdatalen = datalen + rest; // dlina novogo u4astka dannih int newbuflen = newdatalen + 2; // dlina novogo paketa if( blen < 1 ) return false; // TODO: throw? unsigned char *buf = b.getBytesPtr(); if( !buf ) return false; // TODO: throw? // initialize Blowfish key BF_KEY bfkey; if( bUseStaticBFKey ) BF_set_key( &bfkey, (int)this->STATIC_BLOWFISH_KEY_LEN, this->STATIC_BLOWFISH_KEY ); else BF_set_key( &bfkey, (int)this->NEW_BLOWFISH_KEY_LEN, this->NEW_BLOWFISH_KEY ); int offset = 0; int nPasses = 0; unsigned char *outbuf = NULL; // we will decode to this buffer outbuf = (unsigned char *)malloc( newbuflen ); if( !outbuf ) { #ifdef L2LOGINP_DEBUGOUT_BLOWFISH printf( "L2LoginPacket::decodeBlowfish(): memory error!\n" ); #endif // L2LOGINP_DEBUGOUT_BLOWFISH return false; } memset( outbuf, 0, newbuflen ); outbuf[0] = buf[0]; // copy packet len outbuf[1] = buf[1]; nPasses = 0; #ifdef L2LOGINP_DEBUGOUT_BLOWFISH if( bUseStaticBFKey ) printf( "L2LoginPacket::decodeBlowfish(): using STATIC BF KEY\n" ); else printf( "L2LoginPacket::decodeBlowfish(): using DYNAMIC BF KEY\n" ); #endif // L2LOGINP_DEBUGOUT_BLOWFISH for( offset=2; offset<newdatalen; offset+=8 ) { unsigned char data[8] = {0,0,0,0,0,0,0,0}; memcpy( data, buf+offset, 8 ); BF_decrypt( (BF_LONG *)data, &bfkey ); memcpy( outbuf+offset, data, 8 ); nPasses++; } #ifdef L2LOGINP_DEBUGOUT_BLOWFISH printf( "L2LoginPacket::decodeBlowfish(): Decode2: %d passes, %d 8-byte blocks\n", nPasses, n8bc ); //L2LoginPacket *dec2 = new L2LoginPacket( outbuf, blen ); //dec2->dumpToFile( stdout ); //dec2->saveToFileRaw( "pdecodedbf.dat" ); //delete dec2; #endif // L2LOGINP_DEBUGOUT_BLOWFISH this->setBytes( outbuf, blen ); free( outbuf ); #ifdef L2LOGINP_DEBUGOUT_BLOWFISH printf( "L2LoginPacket::decodeBlowfish(): decode complete\n" ); #endif // L2LOGINP_DEBUGOUT_BLOWFISH return true; }
bool L2LoginPacket::encodeBlowfish( bool bUseStaticBFKey ) { unsigned char *buf = this->b.getBytesPtr(); if( !buf ) return false; // TODO: throw unsigned int blen = getPacketSize(); if( blen < 1 ) return false; // TODO: throw //unsigned int datalen = blen - 2; // C4189: local variable is initialized but not referenced //this->padPacketTo8ByteLen(); // manually // initialize Blowfish key BF_KEY bfkey; if( bUseStaticBFKey ) BF_set_key( &bfkey, (int)this->STATIC_BLOWFISH_KEY_LEN, this->STATIC_BLOWFISH_KEY ); else BF_set_key( &bfkey, (int)this->NEW_BLOWFISH_KEY_LEN, this->NEW_BLOWFISH_KEY ); unsigned int offset = 0; int nPasses = 0; unsigned char *outbuf = NULL; // we will decode to this buffer outbuf = (unsigned char *)malloc( blen ); if( !outbuf ) { #ifdef L2LOGINP_DEBUGOUT_BLOWFISH printf( "L2LoginPacket::encodeBlowfish(): memory error!\n" ); #endif // L2LOGINP_DEBUGOUT_BLOWFISH return false; } memset( outbuf, 0, blen ); outbuf[0] = buf[0]; // copy packet len outbuf[1] = buf[1]; #ifdef L2LOGINP_DEBUGOUT_BLOWFISH if( bUseStaticBFKey ) printf( "L2LoginPacket::encodeBlowfish(): using STATIC BF KEY\n" ); else printf( "L2LoginPacket::encodeBlowfish(): using DYNAMIC BF KEY\n" ); printf( "L2LoginPacket::encodeBlowfish(): blen = %u, datalen = %u\n", blen, datalen ); #endif // L2LOGINP_DEBUGOUT_BLOWFISH for( offset=2; offset<real_size-2; offset+=8 ) { unsigned char data[8] = {0,0,0,0,0,0,0,0}; memcpy( data, buf+offset, 8 ); BF_encrypt( (BF_LONG *)data, &bfkey ); memcpy( outbuf+offset, data, 8 ); nPasses++; } #ifdef L2LOGINP_DEBUGOUT_BLOWFISH int n8bc = datalen / 8; printf( "L2LoginPacket::encodeBlowfish(): %d passes, %d 8-byte blocks ==\n", nPasses, n8bc ); //L2LoginPacket dec2; // = new L2LoginPacket(); //printf( "here\n" ); //bool bret = dec2.setBytes( outbuf, real_size ); //if( bret ) printf( "true\n" ); else printf( "false\n" ); //dec2.dumpToFile( stdout ); //delete dec2; #endif // L2LOGINP_DEBUGOUT_BLOWFISH this->setBytes( outbuf, blen ); free( outbuf ); #ifdef L2LOGINP_DEBUGOUT_BLOWFISH printf( "L2LoginPacket::encodeBlowfish(): encode complete\n" ); #endif // L2LOGINP_DEBUGOUT_BLOWFISH return true; }