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;
}
Beispiel #2
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;
}
Beispiel #3
0
/*****************************************************************************
  Function:
	void UDPFlush(void)

  Summary:
	Transmits all pending data in a UDP socket.
	
  Description:
	This function builds a UDP packet with the pending TX data and marks it 
	for transmission over the network interface.  Since UDP is a frame-based
	protocol, this function must be called before returning to the main
	stack loop whenever any data is written.

  Precondition:
	UDPIsPutReady() was previously called to specify the current socket, and
	data has been written to the socket using the UDPPut family of functions.

  Parameters:
	None
	
  Returns:
  	None

  Remarks:
	Note that unlike TCPFlush, UDPFlush must be called before returning to 
	the main stack loop.  There is no auto transmit for UDP segments.
  ***************************************************************************/
void UDPFlush(void)
{
    UDP_HEADER      h;
    UDP_SOCKET_INFO *p;
    WORD			wUDPLength;

    p = &UDPSocketInfo[activeUDPSocket];

	wUDPLength = UDPTxCount + sizeof(UDP_HEADER);

	// Generate the correct UDP header
    h.SourcePort        = swaps(p->localPort);
    h.DestinationPort   = swaps(p->remotePort);
    h.Length            = swaps(wUDPLength);
	h.Checksum 			= 0x0000;
    
	// Calculate IP pseudoheader checksum if we are going to enable 
	// the checksum field
	#if defined(UDP_USE_TX_CHECKSUM)
	{
		PSEUDO_HEADER   pseudoHeader;
		
		pseudoHeader.SourceAddress	= AppConfig.MyIPAddr;
		pseudoHeader.DestAddress    = p->remote.remoteNode.IPAddr;
		pseudoHeader.Zero           = 0x0;
		pseudoHeader.Protocol       = IP_PROT_UDP;
		pseudoHeader.Length			= wUDPLength;
		SwapPseudoHeader(pseudoHeader);
		h.Checksum = ~CalcIPChecksum((BYTE*)&pseudoHeader, sizeof(pseudoHeader));
	}
	#endif

	// Position the hardware write pointer where we will need to 
	// begin writing the IP header
	MACSetWritePtr(BASE_TX_ADDR + sizeof(ETHER_HEADER));
	
	// Write IP header to packet
	IPPutHeader(&p->remote.remoteNode, IP_PROT_UDP, wUDPLength);

    // Write UDP header to packet
    MACPutArray((BYTE*)&h, sizeof(h));
    
	// Calculate the final UDP checksum and write it in, if enabled
	#if defined(UDP_USE_TX_CHECKSUM)
	{
        PTR_BASE	wReadPtrSave;
        WORD		wChecksum;

		wReadPtrSave = MACSetReadPtr(BASE_TX_ADDR + sizeof(ETHER_HEADER) + sizeof(IP_HEADER));
		wChecksum = CalcIPBufferChecksum(wUDPLength);
		if(wChecksum == 0x0000u)
			wChecksum = 0xFFFF;
		MACSetReadPtr(wReadPtrSave);
		MACSetWritePtr(BASE_TX_ADDR + sizeof(ETHER_HEADER) + sizeof(IP_HEADER) + 6);	// 6 is the offset to the Checksum field in UDP_HEADER
		MACPutArray((BYTE*)&wChecksum, sizeof(wChecksum));
	}
	#endif
    
	// Transmit the packet
    MACFlush();

	// Reset packet size counter for the next TX operation
    UDPTxCount = 0;
	LastPutSocket = INVALID_UDP_SOCKET;
}
Beispiel #4
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;
}