boolean CTCPConnection::SendSegment (unsigned nFlags, u32 nSequenceNumber, u32 nAcknowledgmentNumber, const void *pData, unsigned nDataLength) { unsigned nDataOffset = 5; assert (nDataOffset * 4 == sizeof (TTCPHeader)); if (nFlags & TCP_FLAG_SYN) { nDataOffset++; } unsigned nHeaderLength = nDataOffset * 4; unsigned nPacketLength = nHeaderLength + nDataLength; // may wrap assert (nPacketLength >= nHeaderLength); assert (nHeaderLength <= FRAME_BUFFER_SIZE); assert (m_pTxBuffer != 0); TTCPHeader *pHeader = (TTCPHeader *) m_pTxBuffer; pHeader->nSourcePort = le2be16 (m_nOwnPort); pHeader->nDestPort = le2be16 (m_nForeignPort); pHeader->nSequenceNumber = le2be32 (nSequenceNumber); pHeader->nAcknowledgmentNumber = nFlags & TCP_FLAG_ACK ? le2be32 (nAcknowledgmentNumber) : 0; pHeader->nDataOffsetFlags = (nDataOffset << TCP_DATA_OFFSET_SHIFT) | nFlags; pHeader->nWindow = le2be16 (m_nRCV_WND); pHeader->nUrgentPointer = le2be16 (m_nSND_UP); if (nFlags & TCP_FLAG_SYN) { TTCPOption *pOption = (TTCPOption *) pHeader->Options; pOption->nKind = TCP_OPTION_MSS; pOption->nLength = 4; pOption->Data[0] = TCP_CONFIG_MSS >> 8; pOption->Data[1] = TCP_CONFIG_MSS & 0xFF; }
boolean CTCPRejector::SendSegment (unsigned nFlags, u32 nSequenceNumber, u32 nAcknowledgmentNumber) { assert (!(nFlags & TCP_FLAG_SYN)); unsigned nDataOffset = 5; assert (nDataOffset * 4 == sizeof (TTCPHeader)); unsigned nHeaderLength = nDataOffset * 4; unsigned nPacketLength = nHeaderLength; assert (nHeaderLength <= FRAME_BUFFER_SIZE); assert (m_pTxBuffer != 0); TTCPHeader *pHeader = (TTCPHeader *) m_pTxBuffer; pHeader->nSourcePort = le2be16 (m_nOwnPort); pHeader->nDestPort = le2be16 (m_nForeignPort); pHeader->nSequenceNumber = le2be32 (nSequenceNumber); pHeader->nAcknowledgmentNumber = nFlags & TCP_FLAG_ACK ? le2be32 (nAcknowledgmentNumber) : 0; pHeader->nDataOffsetFlags = (nDataOffset << TCP_DATA_OFFSET_SHIFT) | nFlags; pHeader->nWindow = 0; pHeader->nUrgentPointer = 0; pHeader->nChecksum = 0; // must be 0 for calculation pHeader->nChecksum = m_Checksum.Calculate (m_pTxBuffer, nPacketLength); #ifdef TCP_DEBUG CLogger::Get ()->Write (FromTCP, LogDebug, "tx %c%c%c%c%c%c, seq %u, ack %u, win %u, len %u", nFlags & TCP_FLAG_URGENT ? 'U' : '-', nFlags & TCP_FLAG_ACK ? 'A' : '-', nFlags & TCP_FLAG_PUSH ? 'P' : '-', nFlags & TCP_FLAG_RESET ? 'R' : '-', nFlags & TCP_FLAG_SYN ? 'S' : '-', nFlags & TCP_FLAG_FIN ? 'F' : '-', nSequenceNumber, nFlags & TCP_FLAG_ACK ? nAcknowledgmentNumber : 0, 0, 0); #endif assert (m_pNetworkLayer != 0); return m_pNetworkLayer->Send (m_ForeignIP, m_pTxBuffer, nPacketLength, IPPROTO_TCP); }