#include <TCPSerializer.h>
| Public Member Functions | |
| TCPSerializer () | |
| int | serialize (const TCPSegment *source, unsigned char *destbuf, unsigned int bufsize) | 
| int | serialize (const TCPSegment *source, unsigned char *destbuf, unsigned int bufsize, const IPvXAddress &srcIp, const IPvXAddress &destIp) | 
| void | parse (const unsigned char *srcbuf, unsigned int bufsize, TCPSegment *dest) | 
| Static Public Member Functions | |
| static uint16_t | checksum (const void *addr, unsigned int count, const IPvXAddress &srcIp, const IPvXAddress &destIp) | 
Converts between TCPSegment and binary (network byte order) TCP header.
Definition at line 34 of file TCPSerializer.h.
| TCPSerializer::TCPSerializer | ( | ) |  [inline] | 
Definition at line 37 of file TCPSerializer.h.
{}
| uint16_t TCPSerializer::checksum | ( | const void * | addr, | |
| unsigned int | count, | |||
| const IPvXAddress & | srcIp, | |||
| const IPvXAddress & | destIp | |||
| ) |  [static] | 
Calculate checksum with pseudo header.
Definition at line 241 of file TCPSerializer.cc.
Referenced by serialize().
{
    uint32_t sum = TCPIPchecksum::_checksum(addr, count);
    ASSERT(srcIp.wordCount() == destIp.wordCount());
    //sum += srcip;
    sum += htons(TCPIPchecksum::_checksum(srcIp.words(), sizeof(uint32)*srcIp.wordCount()));
    //sum += destip;
    sum += htons(TCPIPchecksum::_checksum(destIp.words(), sizeof(uint32)*destIp.wordCount()));
    sum += htons(count); // TCP length
    sum += htons(IP_PROT_TCP); // PTCL
    while (sum >> 16)
        sum = (sum & 0xFFFF) + (sum >> 16);
    return (uint16_t)~sum;
}
| void TCPSerializer::parse | ( | const unsigned char * | srcbuf, | |
| unsigned int | bufsize, | |||
| TCPSegment * | dest | |||
| ) | 
Puts a packet sniffed from the wire into a TCPSegment. TODO dest why not reference?
Definition at line 157 of file TCPSerializer.cc.
{
    ASSERT(buf);
    ASSERT(tcpseg);
    struct tcphdr const * const tcp = (struct tcphdr * const ) (buf);
    // fill TCP header structure
    tcpseg->setSrcPort(ntohs(tcp->th_sport));
    tcpseg->setDestPort(ntohs(tcp->th_dport));
    tcpseg->setSequenceNo(ntohl(tcp->th_seq));
    tcpseg->setAckNo(ntohl(tcp->th_ack));
    unsigned short hdrLength =tcp->th_offs * 4;
    tcpseg->setHeaderLength(hdrLength);
    // set flags
    unsigned char flags = tcp->th_flags;
    if ((flags & TH_FIN) == TH_FIN)
        tcpseg->setFinBit(true);
    if ((flags & TH_SYN) == TH_SYN)
        tcpseg->setSynBit(true);
    if ((flags & TH_RST) == TH_RST)
        tcpseg->setRstBit(true);
    if ((flags & TH_PUSH) == TH_PUSH)
        tcpseg->setPshBit(true);
    if ((flags & TH_ACK) == TH_ACK)
        tcpseg->setAckBit(true);
    if ((flags & TH_URG) == TH_URG)
        tcpseg->setUrgBit(true);
    tcpseg->setWindow(ntohs(tcp->th_win));
    // Checksum (header checksum): modelled by cMessage::hasBitError()
    tcpseg->setUrgentPointer(ntohs(tcp->th_urp));
    if (hdrLength > TCP_HEADER_OCTETS) // options present?
    {
        unsigned short optionBytes = hdrLength - TCP_HEADER_OCTETS; // TCP_HEADER_OCTETS = 20
        unsigned short optionsCounter = 0; // index for tcpseg->setOptions[]
        unsigned short length = 0;
        for (unsigned short j=0; j<optionBytes; j+=length)
        {
            unsigned char * options = ((unsigned char * )tcp->th_options)+j;
            unsigned short kind = options[0];
            length = options[1];
            TCPOption tmpOption;
            switch(kind)
            {
                case TCPOPTION_END_OF_OPTION_LIST: // EOL
                case TCPOPTION_NO_OPERATION: // NOP
                    length = 1;
                    break;
                default:
                    break;
            } // switch
            // kind
            tmpOption.setKind(kind);
            // length
            tmpOption.setLength(length);
            // value
            int optlen = (length+1)/4;
            tmpOption.setValuesArraySize(optlen);
            for (short int k=0; k<optlen; k++)
            {
                unsigned int value = 0;
                for (short int l=2+4*k; l<length && l<6+4*k; l++)
                {
                    value = (value << 8) + options[l];
                }
                tmpOption.setValues(k, value);
            }
            // write option to tcp header
            tcpseg->setOptionsArraySize(tcpseg->getOptionsArraySize()+1);
            tcpseg->setOptions(optionsCounter,tmpOption);
            optionsCounter++;
        } // for j
    } // if options present
    tcpseg->setByteLength(bufsize);
    tcpseg->setPayloadLength(bufsize - tcpseg->getHeaderLength());
}
| int TCPSerializer::serialize | ( | const TCPSegment * | source, | |
| unsigned char * | destbuf, | |||
| unsigned int | bufsize | |||
| ) | 
Serializes a TCPSegment for transmission on the wire. The checksum is NOT filled in. Returns the length of data written into buffer. TODO msg why not a const reference?
Definition at line 43 of file TCPSerializer.cc.
Referenced by serialize().
{
    ASSERT(buf);
    ASSERT(tcpseg);
    //cMessage* cmsg;
    struct tcphdr *tcp = (struct tcphdr*) (buf);
    //int writtenbytes = sizeof(struct tcphdr)+tcpseg->payloadLength();
    int writtenbytes = tcpseg->getByteLength();
    // fill TCP header structure
    tcp->th_sum = 0;
    tcp->th_sport = htons(tcpseg->getSrcPort());
    tcp->th_dport = htons(tcpseg->getDestPort());
    tcp->th_seq = htonl(tcpseg->getSequenceNo());
    tcp->th_ack = htonl(tcpseg->getAckNo());
    tcp->th_offs = TCP_HEADER_OCTETS / 4;
    // set flags
    unsigned char flags = 0;
    if(tcpseg->getFinBit())
        flags |= TH_FIN;
    if(tcpseg->getSynBit())
        flags |= TH_SYN;
    if(tcpseg->getRstBit())
        flags |= TH_RST;
    if(tcpseg->getPshBit())
        flags |= TH_PUSH;
    if(tcpseg->getAckBit())
        flags |= TH_ACK;
    if(tcpseg->getUrgBit())
        flags |= TH_URG;
    tcp->th_flags = (TH_FLAGS & flags);
    tcp->th_win = htons(tcpseg->getWindow());
    tcp->th_urp = htons(tcpseg->getUrgentPointer());
    unsigned short numOptions = tcpseg->getOptionsArraySize();
    unsigned int lengthCounter = 0;
    unsigned char * options = (unsigned char * )tcp->th_options;
    if (numOptions > 0) // options present?
    {
        unsigned int maxOptLength = tcpseg->getHeaderLength()-TCP_HEADER_OCTETS;
        for (unsigned short i=0; i < numOptions; i++)
        {
            TCPOption option = tcpseg->getOptions(i);
            unsigned short kind = option.getKind();
            unsigned short length = option.getLength(); // length >= 1
            options = ((unsigned char * )tcp->th_options)+lengthCounter;
            lengthCounter += length;
            ASSERT(lengthCounter <= maxOptLength);
            options[0] = kind;
            if(length>1)
            {
                options[1] = length;
            }
            unsigned int optlen = option.getValuesArraySize();
            for(unsigned int k=0; k<optlen; k++)
            {
                unsigned int value = option.getValues(k);
                unsigned int p0 = 2 + 4*k;
                for (unsigned int p = std::min((unsigned int)length-1, 5 + 4*k); p >= p0; p--)
                {
                    options[p] = value & 0xFF;
                    value = value >> 8;
                }
            }
        } // for
        //padding:
        options = (unsigned char * )(tcp->th_options);
        while (lengthCounter % 4)
            options[lengthCounter++] = 0;
        ASSERT(TCP_HEADER_OCTETS+lengthCounter <= TCP_MAX_HEADER_OCTETS);
        tcp->th_offs = (TCP_HEADER_OCTETS+lengthCounter)/4; // TCP_HEADER_OCTETS = 20
    } // if options present
    // write data
    if (tcpseg->getByteLength() > tcpseg->getHeaderLength()) // data present? FIXME TODO: || tcpseg->getEncapsulatedMsg()!=NULL
    {
        unsigned int dataLength = tcpseg->getByteLength() - tcpseg->getHeaderLength();
        // TCPPayloadMessage *tcpP = check_and_cast<TCPPayloadMessage* >(tcpseg->getEncapsulatedMsg()); // FIXME
        char *tcpData = (char *)options+lengthCounter;
        memset(tcpData, 't', dataLength); // fill data part with 't'
        /*
        for (unsigned int i=0; i < dataLength; i++)
        {
            if (i < tcpseg->getPayloadArraySize())
            {
//              tcpData[i] = (unsigned char) tcpP.msg; // FIXME
                tcpData[i] = 't'; // FIXME - write 't' as dummy data
            }
            else
                {tcpData[i] = 't';} // write 't' as dummy data
        }
        */
    }
    return writtenbytes;
}
| int TCPSerializer::serialize | ( | const TCPSegment * | source, | |
| unsigned char * | destbuf, | |||
| unsigned int | bufsize, | |||
| const IPvXAddress & | srcIp, | |||
| const IPvXAddress & | destIp | |||
| ) | 
Serializes a TCPSegment for transmission on the wire. The checksum is NOT filled in. (The kernel does that when sending the frame over a raw socket.) Returns the length of data written into buffer. TODO msg why not a const reference? TODO pseudoheader vs IPv6, pseudoheder.len should calculated by the serialize(), etc
Definition at line 146 of file TCPSerializer.cc.
 1.7.1
 1.7.1