Esempio n. 1
0
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;
	}
Esempio n. 2
0
int CUDPConnection::SendTo (const void *pData, unsigned nLength, int nFlags,
			    CIPAddress	&rForeignIP, u16 nForeignPort)
{
	if (m_nErrno < 0)
	{
		int nErrno = m_nErrno;
		m_nErrno = 0;

		return nErrno;
	}

	if (m_bActiveOpen)
	{
		// ignore rForeignIP and nForeignPort
		return Send (pData, nLength, nFlags);
	}

	if (   nFlags != 0
	    && nFlags != MSG_DONTWAIT)
	{
		return -1;
	}

	unsigned nPacketLength = sizeof (TUDPHeader) + nLength;		// may wrap
	if (   nPacketLength <= sizeof (TUDPHeader)
	    || nPacketLength > FRAME_BUFFER_SIZE)
	{
		return -1;
	}

	assert (m_pNetConfig != 0);
	if (   !m_bBroadcastsAllowed
	    && (   rForeignIP.IsBroadcast ()
	        || rForeignIP == *m_pNetConfig->GetBroadcastAddress ()))
	{
		return -1;
	}

	u8 PacketBuffer[nPacketLength];
	TUDPHeader *pHeader = (TUDPHeader *) PacketBuffer;

	pHeader->nSourcePort = le2be16 (m_nOwnPort);
	pHeader->nDestPort   = le2be16 (nForeignPort);
	pHeader->nLength     = le2be16 (nPacketLength);
	pHeader->nChecksum   = 0;
	
	assert (pData != 0);
	assert (nLength > 0);
	memcpy (PacketBuffer+sizeof (TUDPHeader), pData, nLength);

	m_Checksum.SetSourceAddress (*m_pNetConfig->GetIPAddress ());
	m_Checksum.SetDestinationAddress (rForeignIP);
	pHeader->nChecksum = m_Checksum.Calculate (PacketBuffer, nPacketLength);

	assert (m_pNetworkLayer != 0);
	boolean bOK = m_pNetworkLayer->Send (rForeignIP, PacketBuffer, nPacketLength, IPPROTO_UDP);
	
	return bOK ? nLength : -1;
}
Esempio n. 3
0
int CUDPConnection::Send (const void *pData, unsigned nLength, int nFlags)
{
	if (!m_bActiveOpen)
	{
		return -1;
	}

	if (   nFlags != 0
	    && nFlags != MSG_DONTWAIT)
	{
		return -1;
	}

	unsigned nPacketLength = sizeof (TUDPHeader) + nLength;		// may wrap
	if (   nPacketLength <= sizeof (TUDPHeader)
	    || nPacketLength > FRAME_BUFFER_SIZE)
	{
		return -1;
	}

	u8 *pPacketBuffer = new u8[nPacketLength];
	assert (pPacketBuffer != 0);
	TUDPHeader *pHeader = (TUDPHeader *) pPacketBuffer;

	pHeader->nSourcePort = le2be16 (m_nOwnPort);
	pHeader->nDestPort   = le2be16 (m_nForeignPort);
	pHeader->nLength     = le2be16 (nPacketLength);
	pHeader->nChecksum   = 0;
	
	assert (pData != 0);
	assert (nLength > 0);
	memcpy (pPacketBuffer+sizeof (TUDPHeader), pData, nLength);

	assert (m_pNetConfig != 0);
	m_Checksum.SetSourceAddress (*m_pNetConfig->GetIPAddress ());
	m_Checksum.SetDestinationAddress (m_ForeignIP);
	pHeader->nChecksum = m_Checksum.Calculate (pPacketBuffer, nPacketLength);

	assert (m_pNetworkLayer != 0);
	boolean bOK = m_pNetworkLayer->Send (m_ForeignIP, pPacketBuffer, nPacketLength, IPPROTO_UDP);
	
	delete pPacketBuffer;
	pPacketBuffer = 0;

	return bOK ? nLength : -1;
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
boolean CDNSClient::Resolve (const char *pHostname, CIPAddress *pIPAddress)
{
	assert (pHostname != 0);

	if ('1' <= *pHostname && *pHostname <= '9')
	{
		return FALSE;
	}

	assert (m_pNetSubSystem != 0);
	CIPAddress DNSServer (m_pNetSubSystem->GetConfig ()->GetDNSServer ()->Get ());
	
	CSocket Socket (m_pNetSubSystem, IPPROTO_UDP);
	if (Socket.Connect (DNSServer, 53) != 0)
	{
		return FALSE;
	}

	u8 Buffer[DNS_MAX_MESSAGE_SIZE];
	memset (Buffer, 0, sizeof Buffer);
	TDNSHeader *pDNSHeader = (TDNSHeader *) Buffer;

	u16 nXID = s_nXID++;

	pDNSHeader->nID      = le2be16 (nXID);
	pDNSHeader->nFlags   = BE (DNS_FLAGS_OPCODE_QUERY | DNS_FLAGS_RD);
	pDNSHeader->nQDCount = BE (1);

	u8 *pQuery = Buffer + sizeof (TDNSHeader);

	char Hostname[MAX_HOSTNAME_SIZE];
	strncpy (Hostname, pHostname, MAX_HOSTNAME_SIZE-1);
	Hostname[MAX_HOSTNAME_SIZE-1] = '\0';

	char *pSavePtr;
	size_t nLength;
	char *pLabel = strtok_r (Hostname, ".", &pSavePtr);
	while (pLabel != 0)
	{
		nLength = strlen (pLabel);
		if (   nLength > 255
		    || (int) (nLength+1+1) >= DNS_MAX_MESSAGE_SIZE-(pQuery-Buffer))
		{
			return FALSE;
		}

		*pQuery++ = (u8) nLength;

		strcpy ((char *) pQuery, pLabel);
		pQuery += nLength;

		pLabel = strtok_r (0, ".", &pSavePtr);
	}

	*pQuery++ = '\0';

	TDNSQueryTrailer QueryTrailer;
	QueryTrailer.nQType  = BE (DNS_QTYPE_A);
	QueryTrailer.nQClass = BE (DNS_QCLASS_IN);

	if ((int) (sizeof QueryTrailer) > DNS_MAX_MESSAGE_SIZE-(pQuery-Buffer))
	{
		return FALSE;
	}
	memcpy (pQuery, &QueryTrailer, sizeof QueryTrailer);
	pQuery += sizeof QueryTrailer;
	
	int nSize = pQuery - Buffer;
	assert (nSize <= DNS_MAX_MESSAGE_SIZE);

	unsigned char RecvBuffer[DNS_MAX_MESSAGE_SIZE];
	int nRecvSize;

	unsigned nTry = 1;
	do
	{
		if (   nTry++ > 3
		    || Socket.Send (Buffer, nSize, 0) != nSize)
		{
			return FALSE;
		}

		CScheduler::Get ()->MsSleep (1000);

		nRecvSize = Socket.Receive (RecvBuffer, DNS_MAX_MESSAGE_SIZE, MSG_DONTWAIT);
		assert (nRecvSize < DNS_MAX_MESSAGE_SIZE);
	}
	while (nRecvSize < (int) (sizeof (TDNSHeader)+sizeof (TDNSResourceRecordTrailerAIN)));

	pDNSHeader = (TDNSHeader *) RecvBuffer;
	if (   pDNSHeader->nID != le2be16 (nXID)
	    ||    (pDNSHeader->nFlags & BE (  DNS_FLAGS_QR
	                                    | DNS_FLAGS_OPCODE
	                                    | DNS_FLAGS_TC
	                                    | DNS_FLAGS_RCODE))
	       != BE (DNS_FLAGS_QR | DNS_FLAGS_OPCODE_QUERY | DNS_RCODE_SUCCESS)
	    || pDNSHeader->nQDCount != BE (1)
	    || pDNSHeader->nANCount == BE (0))
	{
		return FALSE;
	}

	u8 *pResponse = RecvBuffer + sizeof (TDNSHeader);

	// parse the query section
	while ((nLength = *pResponse++) > 0)
	{
		pResponse += nLength;
		if (pResponse-RecvBuffer >= nRecvSize)
		{
			return FALSE;
		}
	}

	pResponse += sizeof (TDNSQueryTrailer);
	if (pResponse-RecvBuffer >= nRecvSize)
	{
		return FALSE;
	}

	TDNSResourceRecordTrailerAIN RRTrailer;

	// parse the answer section
	while (1)
	{
		nLength = *pResponse++;
		if ((nLength & 0xC0) == 0xC0)		// check for compression
		{
			pResponse++;
		}
		else
		{
			if (pResponse-RecvBuffer >= nRecvSize)
			{
				return FALSE;
			}

			while ((nLength = *pResponse++) > 0)
			{
				pResponse += nLength;
				if (pResponse-RecvBuffer >= nRecvSize)
				{
					return FALSE;
				}
			}
		}

		if (pResponse-RecvBuffer > (int) (nRecvSize-sizeof RRTrailer))
		{
			return FALSE;
		}

		memcpy (&RRTrailer, pResponse, sizeof RRTrailer);

		if (   RRTrailer.nType     == BE (DNS_QTYPE_A)
		    && RRTrailer.nClass    == BE (DNS_QCLASS_IN)
		    && RRTrailer.nRDLength == BE (DNS_RDLENGTH_AIN))
		{
			break;
		}

		pResponse += DNS_RR_TRAILER_HEADER_LENGTH + BE (RRTrailer.nRDLength);
		if (pResponse-RecvBuffer >= nRecvSize)
		{
			return FALSE;
		}
	}

	assert (pIPAddress != 0);
	pIPAddress->Set (RRTrailer.RData);

	return TRUE;
}