Ejemplo n.º 1
0
/*****************************************************************************
  Function:
	static void DNSCopyRXNameToTX(void)

  Summary:
	Copies a DNS hostname, possibly including name compression, from the RX 
	packet to the TX packet (without name compression in TX case).
	
  Description:
	None

  Precondition:
	RX pointer is set to currently point to the DNS name to copy

  Parameters:
	None

  Returns:
  	None
  ***************************************************************************/
static void DNSCopyRXNameToTX(void)
{
	WORD w;
	BYTE i;
	BYTE len;

	while(1)
	{
		// Get first byte which will tell us if this is a 16-bit pointer or the 
		// length of the first of a series of labels
		if(!UDPGet(&i))
			return;
		
		// Check if this is a pointer, if so, get the reminaing 8 bits and seek to the pointer value
		if((i & 0xC0u) == 0xC0u)
		{
			((BYTE*)&w)[1] = i & 0x3F;
			UDPGet((BYTE*)&w);
			IPSetRxBuffer(sizeof(UDP_HEADER) + w);
			continue;
		}

		// Write the length byte
		len = i;
		UDPPut(len);
		
		// Exit if we've reached a zero length label
		if(len == 0u)
			return;
		
		// Copy all of the bytes in this label	
		while(len--)
		{
			UDPGet(&i);
			UDPPut(i);
		}
	}
}
Ejemplo n.º 2
0
/*****************************************************************************
  Function:
	static void DNSCopyRXNameToTX(UDP_SOCKET s, NET_CONFIG* pNet)

  Summary:
	Copies a DNS hostname, possibly including name compression, from the RX 
	packet to the TX packet (without name compression in TX case).
	
  Description:
	None

  Precondition:
	RX pointer is set to currently point to the DNS name to copy

  Parameters:
	None

  Returns:
  	None
  ***************************************************************************/
static void DNSCopyRXNameToTX(UDP_SOCKET s, NET_CONFIG* pNet)
{
	uint16_t w;
	uint8_t i;
	uint8_t len;

	while(1)
	{
		// Get first byte which will tell us if this is a 16-bit pointer or the 
		// length of the first of a series of labels
		if(!UDPGet(s, &i))
			return;
		
		// Check if this is a pointer, if so, get the reminaing 8 bits and seek to the pointer value
		if((i & 0xC0u) == 0xC0u)
		{
			((uint8_t*)&w)[1] = i & 0x3F;
			UDPGet(s, (uint8_t*)&w);
			IPSetRxBuffer(pNet, sizeof(UDP_HEADER) + w);
			continue;
		}

		// Write the length byte
		len = i;
		UDPPut(s, len);
		
		// Exit if we've reached a zero length label
		if(len == 0u)
			return;
		
		// Copy all of the bytes in this label	
		while(len--)
		{
			UDPGet(s, &i);
			UDPPut(s, i);
		}
	}
}
Ejemplo n.º 3
0
Archivo: ICMP.c Proyecto: CEIT-UQ/RGB
/*********************************************************************
 * Function:        void ICMPProcess(void)
 *
 * PreCondition:    MAC buffer contains ICMP type packet.
 *
 * Input:           *remote: Pointer to a NODE_INFO structure of the 
 *					ping requester
 *					len: Count of how many bytes the ping header and 
 *					payload are in this IP packet
 *
 * Output:          Generates an echo reply, if requested
 *					Validates and sets ICMPFlags.bReplyValid if a 
 *					correct ping response to one of ours is received.
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
void ICMPProcess(NODE_INFO *remote, WORD len)
{
	DWORD_VAL dwVal;

    // Obtain the ICMP header Type, Code, and Checksum fields
    MACGetArray((BYTE*)&dwVal, sizeof(dwVal));
	
	// See if this is an ICMP echo (ping) request
	if(dwVal.w[0] == 0x0008u)
	{
		// Validate the checksum using the Microchip MAC's DMA module
		// The checksum data includes the precomputed checksum in the 
		// header, so a valid packet will always have a checksum of 
		// 0x0000 if the packet is not disturbed.
		if(MACCalcRxChecksum(0+sizeof(IP_HEADER), len))
			return;
	
		// Calculate new Type, Code, and Checksum values
		dwVal.v[0] = 0x00;	// Type: 0 (ICMP echo/ping reply)
		dwVal.v[2] += 8;	// Subtract 0x0800 from the checksum
		if(dwVal.v[2] < 8u)
		{
			dwVal.v[3]++;
			if(dwVal.v[3] == 0u)
				dwVal.v[2]++;
		}
	
	    // Wait for TX hardware to become available (finish transmitting 
	    // any previous packet)
	    while(!IPIsTxReady());

		// Position the write pointer for the next IPPutHeader operation
		// NOTE: do not put this before the IPIsTxReady() call for WF compatbility
	    MACSetWritePtr(BASE_TX_ADDR + sizeof(ETHER_HEADER));
        	
		// Create IP header in TX memory
		IPPutHeader(remote, IP_PROT_ICMP, len);
	
		// Copy ICMP response into the TX memory
		MACPutArray((BYTE*)&dwVal, sizeof(dwVal));
		MACMemCopyAsync(-1, -1, len-4);
		while(!MACIsMemCopyDone());
	
		// Transmit the echo reply packet
	    MACFlush();
	}
#if defined(STACK_USE_ICMP_CLIENT)
	else if(dwVal.w[0] == 0x0000u)	// See if this an ICMP Echo reply to our request
	{
		// Get the sequence number and identifier fields
		MACGetArray((BYTE*)&dwVal, sizeof(dwVal));
		
		// See if the identifier matches the one we sent
		if(dwVal.w[0] != 0xEFBE)	
			return;
	
		if(dwVal.w[1] != wICMPSequenceNumber)
			return;

		// Validate the ICMP checksum field
	    IPSetRxBuffer(0);
		if(CalcIPBufferChecksum(sizeof(ICMP_PACKET)))	// Two bytes of payload were sent in the echo request
			return;
		
		// Flag that we received the response and stop the timer ticking
		ICMPFlags.bReplyValid = 1;
		ICMPTimer = TickGet() - ICMPTimer;
	}
#endif
}
Ejemplo n.º 4
0
BOOL UDPProcess(NODE_INFO *remoteNode, IP_ADDR *localIP, WORD len)
{
    UDP_HEADER h;
    UDP_SOCKET s;
    UDP_PSEUDO_HEADER pseudoHeader;
    WORD_VAL   checksum;

    /*
     * Retrieve UDP header.
     */
    //MACGetArray((BYTE*)&h, sizeof(h));
    MACGetArray(&h, sizeof(UDP_HEADER));

    h.SourcePort        = swaps(h.SourcePort);
    h.DestinationPort   = swaps(h.DestinationPort);
    h.Length            = swaps(h.Length) - sizeof(UDP_HEADER);

      debug_udp("\r\nUDP PROCESS SP=%LX DP=%LX PAYLOAD=%LX ",
            h.SourcePort,
            h.DestinationPort,
            h.Length
         );

   // See if we need to validate the checksum field (0x0000 is disabled)
   if(h.Checksum)
   {
       h.Checksum          = swaps(h.Checksum);

       // Calculate IP pseudoheader checksum.
       pseudoHeader.SourceAddress      = remoteNode->IPAddr;
       pseudoHeader.DestAddress.v[0]   = localIP->v[0];
       pseudoHeader.DestAddress.v[1]   = localIP->v[1];
       pseudoHeader.DestAddress.v[2]   = localIP->v[2];
       pseudoHeader.DestAddress.v[3]   = localIP->v[3];
       pseudoHeader.Zero               = 0x0;
       pseudoHeader.Protocol           = IP_PROT_UDP;
       pseudoHeader.Length             = len;

       SwapPseudoHeader(pseudoHeader);

       checksum.Val = ~CalcIPChecksum(&pseudoHeader,
                                       sizeof(pseudoHeader));


       // Set UDP packet checksum = pseudo header checksum in MAC RAM.
       IPSetRxBuffer(6);
       MACPut(checksum.v[0]);
      // In case if the end of the RX buffer is reached and a wraparound is needed, set the next address to prevent writing to the wrong address.
       IPSetRxBuffer(7);
       MACPut(checksum.v[1]);
       IPSetRxBuffer(0);

       // Now calculate UDP packet checksum in NIC RAM - including
       // pesudo header.
       checksum.Val = CalcIPBufferChecksum(len);

       if ( checksum.Val != h.Checksum )
       {
           debug_udp("INVALID-CS ");
           MACDiscardRx();
           return TRUE;
       }
   }

    s = FindMatching_UDP_Socket(&h, remoteNode, localIP);
    if ( s == INVALID_UDP_SOCKET )
    {
        /*
         * If there is no matching socket, There is no one to handle
         * this data.  Discard it.
         */
        debug_udp("INVALID-SOCKET ");
        MACDiscardRx();
    }
    else {
        UDPSocketInfo[s].RxCount = h.Length;
        UDPSocketInfo[s].Flags.bFirstRead = TRUE;

    debug_udp("MATCH AS:%U ", s);
    /*debug_udp("MAC-%X:%X:%X:%X:%X:%X",
         remoteNode->MACAddr.v[0],
         remoteNode->MACAddr.v[1],
         remoteNode->MACAddr.v[2],
         remoteNode->MACAddr.v[3],
         remoteNode->MACAddr.v[4],
         remoteNode->MACAddr.v[5]
      );*/
    }

    return TRUE;
}
Ejemplo n.º 5
0
/*****************************************************************************
  Function:
	void UDPSetRxBuffer(WORD wOffset)

  Summary:
	Moves the pointer within the RX buffer.
	
  Description:
	This function allows the read location within the RX buffer to be 
	specified.  Future calls to UDPGet and UDPGetArray will read data from
	the indicated location forward.

  Precondition:
	UDPInit() must have been previously called and a socket is currently 
	active.

  Parameters:
	wOffset - Offset from beginning of UDP packet data payload to place the
		read pointer.

  Returns:
  	None
  ***************************************************************************/
void UDPSetRxBuffer(WORD wOffset)
{
	IPSetRxBuffer(wOffset+sizeof(UDP_HEADER));
	wGetOffset = wOffset;
}
Ejemplo n.º 6
0
/*****************************************************************************
  Function:
	BOOL UDPProcess(NODE_INFO *remoteNode, IP_ADDR *localIP, WORD len)

  Summary:
	Handles an incoming UDP segment.
	
  Description:
	This function handles an incoming UDP segment to determine if it is 
	acceptable and should be handed to one of the stack applications for
	processing.

  Precondition:
	UDPInit() has been called an a UDP segment is ready in the MAC buffer.

  Parameters:
	remoteNode - The remote node that sent this segment.
	localIP - The destination IP address for this segment.
	len - Total length of the UDP segment.
	
  Return Values:
  	TRUE - A valid packet is waiting and the stack applications should be
  		called to handle it.
  	FALSE - The packet was discarded.
  ***************************************************************************/
BOOL UDPProcess(NODE_INFO *remoteNode, IP_ADDR *localIP, WORD len)
{
    UDP_HEADER		h;
    UDP_SOCKET		s;
    PSEUDO_HEADER	pseudoHeader;
    DWORD_VAL		checksums;

	UDPRxCount = 0;

    // Retrieve UDP header.
    MACGetArray((BYTE*)&h, sizeof(h));

    h.SourcePort        = swaps(h.SourcePort);
    h.DestinationPort   = swaps(h.DestinationPort);
    h.Length            = swaps(h.Length) - sizeof(UDP_HEADER);

	// See if we need to validate the checksum field (0x0000 is disabled)
	if(h.Checksum)
	{
	    // Calculate IP pseudoheader checksum.
	    pseudoHeader.SourceAddress		= remoteNode->IPAddr;
	    pseudoHeader.DestAddress.Val	= localIP->Val;
	    pseudoHeader.Zero				= 0x0;
	    pseudoHeader.Protocol			= IP_PROT_UDP;
	    pseudoHeader.Length				= len;

	    SwapPseudoHeader(pseudoHeader);
	
	    checksums.w[0] = ~CalcIPChecksum((BYTE*)&pseudoHeader,
	                                    sizeof(pseudoHeader));
	
	
	    // Now calculate UDP packet checksum in NIC RAM -- should match pseudoHeader
	    IPSetRxBuffer(0);
	    checksums.w[1] = CalcIPBufferChecksum(len);
	
	    if(checksums.w[0] != checksums.w[1])
	    {
	        MACDiscardRx();
	        return FALSE;
	    }
	}

    s = FindMatchingSocket(&h, remoteNode, localIP);
    if(s == INVALID_UDP_SOCKET)
    {
        // If there is no matching socket, There is no one to handle
        // this data.  Discard it.
        MACDiscardRx();
		return FALSE;
    }
    else
    {
		SocketWithRxData = s;
        UDPRxCount = h.Length;
        Flags.bFirstRead = 1;
		Flags.bWasDiscarded = 0;
    }


    return TRUE;
}
Ejemplo n.º 7
0
/**
 * Performs UDP related tasks. Must continuesly be called.
 *
 * @preCondition    UDPInit() is already called AND <br>
 *                  UDP segment is ready in MAC buffer
 *
 * @param remoteNode    Remote node info
 * @param len           Total length of UDP semgent
 * @param destIP        The Destination IP Address of the currently received packet
 *
 * @return          TRUE if this function has completed its task <br>
 *                  FALSE otherwise
 */
BOOL UDPProcess(NODE_INFO *remoteNode, IP_ADDR *destIP, WORD len)
{
    UDP_HEADER h;
    UDP_SOCKET s;
    PSEUDO_HEADER   pseudoHeader;
    WORD_VAL        checksum;
    #if defined(UDP_SPEED_OPTIMIZE)
    BYTE temp;
    #endif

    //Retrieve UDP header. The data is read from the current MAC RX Buffer
    MACGetArray((BYTE*)&h, sizeof(h));

    #if defined(UDP_SPEED_OPTIMIZE)
        temp                    = h.SourcePort.v[0];
        h.SourcePort.v[0]       = h.SourcePort.v[1];
        h.SourcePort.v[1]       = temp;

        temp                    = h.DestinationPort.v[0];
        h.DestinationPort.v[0]  = h.DestinationPort.v[1];
        h.DestinationPort.v[1]  = temp;

        //Will an overflow occur after the subtraction?
        if ((BYTE)sizeof(UDP_HEADER) > h.Length.v[1]) {
            temp                = h.Length.v[0] - 1;
        }
        else {
            temp                = h.Length.v[0];
        }
        h.Length.v[0]           = h.Length.v[1] - (BYTE)sizeof(UDP_HEADER);
        h.Length.v[1]           = temp;
    #else
        h.SourcePort.Val        = swaps(h.SourcePort.Val);
        h.DestinationPort.Val   = swaps(h.DestinationPort.Val);
        h.Length.Val            = swaps(h.Length.Val) - sizeof(UDP_HEADER);
    #endif

    // See if we need to validate the checksum field (0x0000 is disabled)
    if(h.Checksum.Val)
    {
        #if defined(UDP_SPEED_OPTIMIZE)
            temp                    = h.Checksum.v[0];
            h.Checksum.v[0]         = h.Checksum.v[1];
            h.Checksum.v[1]         = temp;
        #else
            h.Checksum.Val          = swaps(h.Checksum.Val);
        #endif

        // Calculate IP pseudoheader checksum.
        pseudoHeader.SourceAddress      = remoteNode->IPAddr;
        pseudoHeader.DestAddress.v[0]   = destIP->v[0];
        pseudoHeader.DestAddress.v[1]   = destIP->v[1];
        pseudoHeader.DestAddress.v[2]   = destIP->v[2];
        pseudoHeader.DestAddress.v[3]   = destIP->v[3];
        pseudoHeader.Zero               = 0x0;
        pseudoHeader.Protocol           = IP_PROT_UDP;
        pseudoHeader.Length             = len;

        SwapPseudoHeader(pseudoHeader);

        checksum.Val = ~CalcIPChecksum((BYTE*)&pseudoHeader,
                                        sizeof(pseudoHeader));


        // Set UCP packet checksum = pseudo header checksum in MAC RAM.
        IPSetRxBuffer(6);
        MACPut(checksum.v[0]);
        // In case if the end of the RX buffer is reached and a wraparound is needed, set the next address to prevent writing to the wrong address.
        IPSetRxBuffer(7);
        MACPut(checksum.v[1]);
        IPSetRxBuffer(0);   //Set current receive buffer access pointer to first byte of IP data = first byte of TCP header

        // Now calculate UDP packet checksum in NIC RAM - including
        // pesudo header.
        checksum.Val = CalcIPBufferChecksum(len);

        if ( checksum.Val != h.Checksum.Val )
        {
            MACDiscardRx(); //Discard the contents of the current RX buffer
            return TRUE;
        }
    }

    s = FindMatchingSocket(&h, remoteNode, destIP);
    if ( s == INVALID_UDP_SOCKET )
    {
         // If there is no matching socket, There is no one to handle
         // this data.  Discard it.
        MACDiscardRx(); //Discard the contents of the current RX buffer
    }
    else
    {
        UDPSocketInfo[s].RxCount = h.Length.Val;
        UDPSocketInfo[s].Flags.bFirstRead = TRUE;
    }

    return TRUE;
}
Ejemplo n.º 8
0
/*****************************************************************************
  Function:
    void UDPSetRxBuffer(uint16_t wOffset)

  Summary:
    Moves the pointer within the RX buffer.

  Description:
    This function allows the read location within the RX buffer to be
    specified.  Future calls to UDPGet and UDPGetArray will read data from
    the indicated location forward.

  Precondition:
    UDPInit() must have been previously called and a socket is currently
    active.

  Parameters:
    wOffset - Offset from beginning of UDP packet data payload to place the
        read pointer.

  Returns:
    None
  ***************************************************************************/
void UDPSetRxBuffer(uint16_t wOffset)
{
    IPSetRxBuffer(wOffset+sizeof(UDP_HEADER));
    wGetOffset = wOffset;
}