#include "cygwin.h" #include "sPacket.h" #include "cSocket.h" #include "protocol.h" #include "opcodes.h" int sPacket::count = 0; #define tReadOK 9 void sPacket::Proto (uint8_t p ) {{{ ASSERT(data != NULL); *(reinterpret_cast(data + 0)) = proto = p; }}} void sPacket::Paylen(size_t p ) {{{ ASSERT(data != NULL); *(reinterpret_cast(data + 1)) = pay_len = p; }}} void sPacket::Opcode(uint8_t p ) {{{ ASSERT(data != NULL); *(reinterpret_cast(data + 5)) = opcode = p; }}} sPacket ::sPacket () {{{ size = 0; count++; data = NULL; status = 0; pos = 0; }}} sPacket ::~sPacket (void) {{{ if (data != NULL) free (data); if (status != 103 && status >= 101) { printf("sPacket status %i\n", status); ASSERT(0); } count--; }}} int sPacket::Read (class cSocket *Socket) {{{ ASSERT (Socket != NULL); ASSERT(Socket->validSocket()); ASSERT (status != -1); if (status <= 0) {{{ // Lese Header vorbereiten pos = 6; size = 6; if (data == NULL) { data = reinterpret_cast(MALLOC (size)); data_length = size; } else { if (data_length < size) { data = reinterpret_cast(REALLOC (data, size)); data_length = size; } } Proto (0); status = 1; }}} if (status == 1) {{{ size_t ret = Socket->Read (data + 6 - pos, pos); // never return - value pos -= ret; if (pos > 0) return 0; proto = *(reinterpret_cast(data + 0)); pay_len = *(reinterpret_cast(data + 1)); opcode = *(reinterpret_cast(data + 5)); if (proto != OP_EDONKEYHEADER && proto != 0xD4 && proto != 0xC5) { Socket->Close(); status = -1; return -1; } status = (pay_len == 1)?tReadOK:2; if (status == tReadOK) return 0; size = 5 + pay_len; if (size > 30000) {{{ // Limit packet size printf("OVERSIZE PACKET\n"); Socket->Close(); status = 3; return 0; }}} ASSERT(data != NULL); if (data_length < size) { data = reinterpret_cast(REALLOC (data, size)); data_length = size; } }}} if (status == 2) {{{ // Lese Daten size_t missing = pay_len - pos - 1; size_t ret = Socket->Read (data + 6 + pos, missing); // never return - value if (ret == 0) return 0; pos += ret; if (pos == pay_len - 1) { pos = 0; status = tReadOK; return 1; } }}} return 0; // Solte nie hier ankommen }}} int sPacket::Send (class cSocket *Socket) {{{ ASSERT (Full()); ASSERT (Socket != NULL); ASSERT (status == 101); ASSERT(Socket->validSocket()); Socket->Write (data, size); // -2 (-1 Byte wegen array[1] und Code ist im Header) status = 103; return 1; }}} bool sPacket::GET_HASH (tHash &dst) {{{ ASSERT (tReadOK == status); ASSERT (pay_len - pos >= sizeof(tHash)); ASSERT (dst != NULL); memcpy (dst, data + 6 + pos, sizeof(tHash)); pos += sizeof(tHash); return true; }}} float sPacket::GET_F4 (void) {{{ float val = 0; ASSERT (tReadOK == status); ASSERT (pay_len - pos >= sizeof (val)); memcpy (&val, data + 6 + pos, sizeof(val)); pos += sizeof(val); return val; }}} uint32_t sPacket::GET_U4 (void) {{{ uint32_t val = 0; ASSERT (tReadOK == status); ASSERT (pay_len - pos >= sizeof (val)); memcpy (&val, 6 + data + pos, sizeof(val)); pos += sizeof(val); return ctol32(val); }}} uint16_t sPacket::GET_U2 (void) {{{ uint16_t val = 0; ASSERT (tReadOK == status); ASSERT (pay_len - pos >= sizeof (val)); memcpy (&val, 6 + data + pos, sizeof(val)); pos += sizeof(val); return ctol16(val); }}} uint8_t sPacket::GET_U1 (void) {{{ uint8_t val = 0; ASSERT (tReadOK == status); ASSERT (pay_len - pos >= sizeof (val)); memcpy (&val, 6 + data + pos, sizeof(val)); pos += sizeof(val); return val; }}} char* sPacket::GET_S2 (void) {{{ uint16_t Size = GET_U2 (); ASSERT (tReadOK == status); if(Size == 0) return STRDUP (""); char *val = reinterpret_cast(MALLOC (Size + 1)); memcpy (val, data + 6 + pos, Size); val[Size] = 0; pos += Size; return val; }}} void sPacket::GET_BLIND(unsigned len) {{{ ASSERT (tReadOK == status); ASSERT (pay_len - pos >= len); pos += len; }}} unsigned char *sPacket::DATA (void) {{{ return data + 6 + pos; }}} void sPacket::Dump (void) const {{{ printf("\r\nprotokol:%02x\r\n", proto); printf("length : %u\r\n" , pay_len); printf("position : %#08X\r\n", pos); unsigned tmp = opcode; printf("command : 0x%02hx\r\n", tmp); for (uint32_t i=0; i < pay_len - 1; i++) { if(i%16==0) printf("\r\n%#08X ", i); tmp = data[6+i]; printf ("%02hx ", tmp); } printf("\r\n"); }}} bool sPacket::readReset(void) {{{ if (status != tReadOK) { printf("Status %i\r\n", status); } ASSERT (status == tReadOK); if (pos != pay_len) { // printf("opcode 0x%02X\n", opcode); // printf("pos %i\n", pos); // printf("pay_len = %i\n", pay_len); // Dump(); // abort(); } status = 0; pos = 0; return true; }}} /* * vim600: fdm=marker */