mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-15 10:54:22 -05:00
250 lines
5.2 KiB
C++
250 lines
5.2 KiB
C++
|
/*
|
||
|
* "$Id: tcppacket.cc,v 1.3 2007-02-18 21:46:50 rmf24 Exp $"
|
||
|
*
|
||
|
* TCP-on-UDP (tou) network interface for RetroShare.
|
||
|
*
|
||
|
* Copyright 2004-2006 by Robert Fernie.
|
||
|
*
|
||
|
* This library is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU Library General Public
|
||
|
* License Version 2 as published by the Free Software Foundation.
|
||
|
*
|
||
|
* This library is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* Library General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU Library General Public
|
||
|
* License along with this library; if not, write to the Free Software
|
||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||
|
* USA.
|
||
|
*
|
||
|
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#include "tcppacket.h"
|
||
|
|
||
|
/*
|
||
|
* #include <arpa/inet.h>
|
||
|
*/
|
||
|
|
||
|
#include "tou_net.h" /* for winsock.h -> htons etc */
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include <iostream>
|
||
|
|
||
|
/* NOTE That these BIT #defines will only
|
||
|
* work on little endian machines....
|
||
|
* due to the ntohs ...
|
||
|
*/
|
||
|
|
||
|
/* flags 16bit is:
|
||
|
*
|
||
|
* || 0 1 2 3 | 4 5 6 7 || 8 9 | 10 11 12 13 14 15 ||
|
||
|
* <- HLen -> <--- unused ---> <---- flags ------->
|
||
|
* URG PSH SYN
|
||
|
* ACK RST FIN
|
||
|
*
|
||
|
*
|
||
|
* So in little endian world.
|
||
|
* 0 & 1 -> unused...
|
||
|
* URG -> bit 2 => 0x0004
|
||
|
* ACK -> bit 3 => 0x0008
|
||
|
* PSH -> bit 4 => 0x0010
|
||
|
* RST -> bit 5 => 0x0020
|
||
|
* SYN -> bit 6 => 0x0040
|
||
|
* FIN -> bit 7 => 0x0080
|
||
|
*
|
||
|
* and second byte 0-3 -> hlen, 4-7 unused.
|
||
|
*/
|
||
|
|
||
|
#define TCP_URG_BIT 0x0004
|
||
|
#define TCP_ACK_BIT 0x0008
|
||
|
#define TCP_PSH_BIT 0x0010
|
||
|
#define TCP_RST_BIT 0x0020
|
||
|
#define TCP_SYN_BIT 0x0040
|
||
|
#define TCP_FIN_BIT 0x0080
|
||
|
|
||
|
|
||
|
TcpPacket::TcpPacket(uint8 *ptr, int size)
|
||
|
:data(0), datasize(0), seqno(0), ackno(0), hlen_flags(0),
|
||
|
winsize(0), ts(0), retrans(0)
|
||
|
{
|
||
|
if (size > 0)
|
||
|
{
|
||
|
datasize = size;
|
||
|
data = (uint8 *) malloc(datasize);
|
||
|
memcpy(data, (void *) ptr, size);
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
TcpPacket::TcpPacket() /* likely control packet */
|
||
|
:data(0), datasize(0), seqno(0), ackno(0), hlen_flags(0),
|
||
|
winsize(0), ts(0), retrans(0)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
TcpPacket::~TcpPacket()
|
||
|
{
|
||
|
if (data)
|
||
|
free(data);
|
||
|
}
|
||
|
|
||
|
|
||
|
int TcpPacket::writePacket(void *buf, int &size)
|
||
|
{
|
||
|
if (size < TCP_PSEUDO_HDR_SIZE + datasize)
|
||
|
{
|
||
|
size = 0;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
/* byte: 0 => uint16 srcport = 0 */
|
||
|
*((uint16 *) &(((uint8 *) buf)[0])) = htons(0);
|
||
|
|
||
|
/* byte: 2 => uint16 destport = 0 */
|
||
|
*((uint16 *) &(((uint8 *) buf)[2])) = htons(0);
|
||
|
|
||
|
/* byte: 4 => uint32 seqno */
|
||
|
*((uint32 *) &(((uint8 *) buf)[4])) = htonl(seqno);
|
||
|
|
||
|
/* byte: 8 => uint32 ackno */
|
||
|
*((uint32 *) &(((uint8 *) buf)[8])) = htonl(ackno);
|
||
|
|
||
|
/* byte: 12 => uint16 len + flags */
|
||
|
*((uint16 *) &(((uint8 *) buf)[12])) = htons(hlen_flags);
|
||
|
|
||
|
/* byte: 14 => uint16 winsize */
|
||
|
*((uint16 *) &(((uint8 *) buf)[14])) = htons(winsize);
|
||
|
|
||
|
/* byte: 16 => uint16 chksum */
|
||
|
*((uint16 *) &(((uint8 *) buf)[16])) = htons(0);
|
||
|
|
||
|
/* byte: 18 => uint16 urgptr */
|
||
|
*((uint16 *) &(((uint8 *) buf)[18])) = htons(0);
|
||
|
|
||
|
/* total 20 bytes */
|
||
|
|
||
|
/* now the data */
|
||
|
memcpy((void *) &(((uint8 *) buf)[20]), data, datasize);
|
||
|
|
||
|
return size = TCP_PSEUDO_HDR_SIZE + datasize;
|
||
|
}
|
||
|
|
||
|
|
||
|
int TcpPacket::readPacket(void *buf, int size)
|
||
|
{
|
||
|
if (size < TCP_PSEUDO_HDR_SIZE)
|
||
|
{
|
||
|
std::cerr << "TcpPacket::readPacket() Failed Too Small!";
|
||
|
std::cerr << std::endl;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
/* byte: 0 => uint16 srcport = 0 *******************
|
||
|
*((uint16 *) &(((uint8 *) buf)[0])) = htons(0);
|
||
|
***********/
|
||
|
|
||
|
/* byte: 2 => uint16 destport = 0 ******************
|
||
|
*((uint16 *) &(((uint8 *) buf)[2])) = htons(0);
|
||
|
***********/
|
||
|
|
||
|
/* byte: 4 => uint32 seqno */
|
||
|
seqno = ntohl( *((uint32 *) &(((uint8 *) buf)[4])) );
|
||
|
|
||
|
/* byte: 8 => uint32 ackno */
|
||
|
ackno = ntohl( *((uint32 *) &(((uint8 *) buf)[8])) );
|
||
|
|
||
|
/* byte: 12 => uint16 len + flags */
|
||
|
hlen_flags = ntohs( *((uint16 *) &(((uint8 *) buf)[12])) );
|
||
|
|
||
|
/* byte: 14 => uint16 winsize */
|
||
|
winsize = ntohs( *((uint16 *) &(((uint8 *) buf)[14])) );
|
||
|
|
||
|
/* byte: 16 => uint16 chksum *************************
|
||
|
*((uint16 *) &(((uint8 *) buf)[16])) = htons(0);
|
||
|
***********/
|
||
|
|
||
|
/* byte: 18 => uint16 urgptr *************************
|
||
|
*((uint16 *) &(((uint8 *) buf)[18])) = htons(0);
|
||
|
***********/
|
||
|
|
||
|
/* total 20 bytes */
|
||
|
|
||
|
if (data)
|
||
|
{
|
||
|
free(data);
|
||
|
}
|
||
|
datasize = size - TCP_PSEUDO_HDR_SIZE;
|
||
|
data = (uint8 *) malloc(datasize);
|
||
|
|
||
|
/* now the data */
|
||
|
memcpy(data, (void *) &(((uint8 *) buf)[20]), datasize);
|
||
|
|
||
|
return size;
|
||
|
}
|
||
|
|
||
|
/* flags */
|
||
|
bool TcpPacket::hasSyn()
|
||
|
{
|
||
|
return (hlen_flags & TCP_SYN_BIT);
|
||
|
}
|
||
|
|
||
|
bool TcpPacket::hasFin()
|
||
|
{
|
||
|
return (hlen_flags & TCP_FIN_BIT);
|
||
|
}
|
||
|
|
||
|
bool TcpPacket::hasAck()
|
||
|
{
|
||
|
return (hlen_flags & TCP_ACK_BIT);
|
||
|
}
|
||
|
|
||
|
bool TcpPacket::hasRst()
|
||
|
{
|
||
|
return (hlen_flags & TCP_RST_BIT);
|
||
|
}
|
||
|
|
||
|
|
||
|
void TcpPacket::setSyn()
|
||
|
{
|
||
|
hlen_flags |= TCP_SYN_BIT;
|
||
|
}
|
||
|
|
||
|
void TcpPacket::setFin()
|
||
|
{
|
||
|
hlen_flags |= TCP_FIN_BIT;
|
||
|
}
|
||
|
|
||
|
void TcpPacket::setRst()
|
||
|
{
|
||
|
hlen_flags |= TCP_RST_BIT;
|
||
|
}
|
||
|
|
||
|
void TcpPacket::setAckFlag()
|
||
|
{
|
||
|
hlen_flags |= TCP_ACK_BIT;
|
||
|
}
|
||
|
|
||
|
void TcpPacket::setAck(uint32 val)
|
||
|
{
|
||
|
setAckFlag();
|
||
|
ackno = val;
|
||
|
}
|
||
|
|
||
|
uint32 TcpPacket::getAck()
|
||
|
{
|
||
|
return ackno;
|
||
|
}
|
||
|
|
||
|
|