예제 #1
0
std::ostream&
pw::ApnsResponsePacket::write (std::ostream& os) const
{
	char b[getPacketSize()];
	this->_write(b);
	return os.write(b, getPacketSize());
}
예제 #2
0
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();
}
예제 #3
0
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;
    }
}
예제 #4
0
std::string&
pw::ApnsPacket::write (std::string& ostr) const
{
	ostr.resize(getPacketSize());
	this->_write(const_cast<char*>(ostr.c_str()), ostr.size());
	return ostr;
}
예제 #5
0
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);
}
예제 #6
0
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--;
  }
}
예제 #7
0
파일: ospf.c 프로젝트: SunnyQ/cmu
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;
}
예제 #8
0
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);
      }
    }
  }
}
예제 #9
0
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;
  }
}
예제 #10
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;
}
예제 #11
0
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;
}
예제 #12
0
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;
}
예제 #13
0
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;
}
예제 #14
0
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;
}
예제 #15
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;
}
예제 #16
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;
    }

  }
}
예제 #17
0
//---------------------------------------------------------------------------
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;
}
예제 #18
0
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;
}
예제 #19
0
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;
}