/********************************************************************* * Function: BOOL UDPProcess(NODE_INFO* remoteNode, * WORD len) * * PreCondition: UDPInit() is already called AND * UDP segment is ready in MAC buffer * * Input: remoteNode - Remote node info * len - Total length of UDP semgent. * * Output: TRUE if this function has completed its task * FALSE otherwise * * Side Effects: None * * Overview: None * * Note: None ********************************************************************/ BOOL UDPProcess(NODE_INFO *remoteNode, WORD len) { UDP_HEADER h; UDP_SOCKET s; /* * 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);; h.Checksum = swaps(h.Checksum); s = FindMatchingSocket(&h, remoteNode); if ( s == INVALID_UDP_SOCKET ) { /* * If there is no matching socket, There is no one to handle * this data. Discard it. */ MACDiscardRx(); } else { UDPSocketInfo[s].RxCount = h.Length; UDPSocketInfo[s].Flags.bFirstRead = TRUE; } return TRUE; }
/***************************************************************************** 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; }
/** * 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; }