Esempio n. 1
0
/*********************************************************************
 * Function:        BOOL UDPGet(BYTE *v)
 *
 * PreCondition:    UDPInit() is already called     AND
 *                  UDPIsGetReady(s) == TRUE
 *
 * Input:           v       - Buffer to receive UDP data byte
 *
 * Output:          TRUE    if a data byte was read
 *                  FALSE   if no data byte was read or available
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            This function fetches data from an active UDP
 *                  socket as set by UDPIsGetReady() call.
 ********************************************************************/
BOOL UDPGet(BYTE *v)
{
    // CALLER MUST MAKE SURE THAT THERE IS ENOUGH DATA BYTE IN BUFFER
    // BEFORE CALLING THIS FUNCTION.
    // USE UDPIsGetReady() TO CONFIRM.

    if ( UDPSocketInfo[activeUDPSocket].RxCount == 0 )
        return FALSE;

    // If if this very first read to packet, set MAC Rx Pointer to
    // beginig of UDP data area.
    if ( UDPSocketInfo[activeUDPSocket].Flags.bFirstRead )
    {
        UDPSocketInfo[activeUDPSocket].Flags.bFirstRead = FALSE;
        UDPSetRxBuffer(0);
    }

    *v = MACGet();

    UDPSocketInfo[activeUDPSocket].RxCount--;

    if ( UDPSocketInfo[activeUDPSocket].RxCount == 0 )
    {
        MACDiscardRx();
    }

    return TRUE;
}
Esempio n. 2
0
/**
 * Read the requested number of bytes from the active UDP socket into
 * the given buffer.
 *
 * Note: This function fetches data from an active UDP socket as set by
 * UDPIsGetReady() call.
 *
 * @preCondition    UDPInit() is already called     AND
 *                  UDPIsGetReady(s) == TRUE
 *
 * @param[in] buffer   Buffer to hold received data.
 * @param count         Buffer length
 *
 * @return          Number of bytes loaded into buffer.
 */
WORD UDPGetArray(BYTE *buffer, WORD count)
{
    WORD bytesRead;
    
    if ( UDPSocketInfo[activeUDPSocket].RxCount == 0 )
        return 0;

    // If if this very first read to packet, set MAC Rx Pointer to
    // beginig of UDP data area.
    if ( UDPSocketInfo[activeUDPSocket].Flags.bFirstRead )
    {
        UDPSocketInfo[activeUDPSocket].Flags.bFirstRead = FALSE;
        UDPSetRxBuffer(0);
    }

    //If more bytes requested then are left in the receive buffer, adjust count
    if (count > UDPSocketInfo[activeUDPSocket].RxCount) {
        count = UDPSocketInfo[activeUDPSocket].RxCount;
    }

    //Read the requested amount of data from the current MAC receive buffer
    bytesRead = MACGetArray(buffer, count);

    UDPSocketInfo[activeUDPSocket].RxCount -= bytesRead;

    if ( UDPSocketInfo[activeUDPSocket].RxCount == 0 )
    {
        MACDiscardRx(); //Discard the contents of the current RX buffer
    }

    return count;
}
Esempio n. 3
0
/*****************************************************************************
  Function:
	WORD UDPIsGetReady(UDP_SOCKET s)

  Summary:
	Determines how many bytes can be read from the UDP socket.
	
  Description:
	This function determines if bytes can be read from the specified UDP
	socket.  It also prepares the UDP module for reading by setting the 
	indicated socket as the currently active connection.

  Precondition:
	UDPInit() must have been previously called.

  Parameters:
	s - The socket to be made active (which has already been opened or is
		listening)

  Returns:
  	The number of bytes that can be read from this socket.
  ***************************************************************************/
WORD UDPIsGetReady(UDP_SOCKET s)
{
    activeUDPSocket = s;
	if(SocketWithRxData != s)
		return 0;

    // If this is the very first time we are accessing this packet, 
    // move the read point to the begining of the packet.
    if(Flags.bFirstRead)
    {
        Flags.bFirstRead = 0;
        UDPSetRxBuffer(0);
    }

    return UDPRxCount - wGetOffset;
}
Esempio n. 4
0
/*****************************************************************************
Function:
  void _DHCPReceive(void)

Description:
  Receives and parses a DHCP message.

Precondition:
  A DHCP message is waiting in the UDP buffer.

Parameters:
  None

Returns:
  One of the DCHP_TYPE* contants.
***************************************************************************/
static BYTE _DHCPReceive(void)
{
	/*********************************************************************
	DHCP PACKET FORMAT AS PER RFC 1541

	0                   1                   2                   3
	0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	|     op (1)    |   htype (1)   |   hlen (1)    |   hops (1)    |
	+---------------+---------------+---------------+---------------+
	|                            xid (4)                            |
	+-------------------------------+-------------------------------+
	|           secs (2)            |           flags (2)           |
	+-------------------------------+-------------------------------+
	|                          ciaddr  (4)                          |
	+---------------------------------------------------------------+
	|                          yiaddr  (4)                          |
	+---------------------------------------------------------------+
	|                          siaddr  (4)                          |
	+---------------------------------------------------------------+
	|                          giaddr  (4)                          |
	+---------------------------------------------------------------+
	|                                                               |
	|                          chaddr  (16)                         |
	|                                                               |
	|                                                               |
	+---------------------------------------------------------------+
	|                                                               |
	|                          sname   (64)                         |
	+---------------------------------------------------------------+
	|                                                               |
	|                          file    (128)                        |
	+---------------------------------------------------------------+
	|                                                               |
	|                          options (312)                        |
	+---------------------------------------------------------------+

	********************************************************************/
	BYTE v;
	BYTE i, j;
	BYTE type;
	BOOL lbDone;
	DWORD tempServerID;


	// Assume unknown message until proven otherwise.
	type = DHCP_UNKNOWN_MESSAGE;

	UDPGet(&v);                             // op

	// Make sure this is BOOT_REPLY.
	if ( v == BOOT_REPLY )
	{
		// Jump to chaddr field (Client Hardware Address -- our MAC address for 
		// Ethernet and WiFi networks) and verify that this message is directed 
		// to us before doing any other processing.
		UDPSetRxBuffer(28);		// chaddr field is at offset 28 in the UDP packet payload -- see DHCP packet format above
		for ( i = 0; i < 6u; i++ )
		{
			UDPGet(&v);
			if ( v != AppConfig.MyMACAddr.v[i])
				goto UDPInvalid;
		}

		// Check to see if this is the first offer.  If it is, record its 
		// yiaddr value ("Your (client) IP address") so that we can REQUEST to 
		// use it later.
		if(!DHCPClient.flags.bits.bOfferReceived)
		{
			UDPSetRxBuffer(16);
			UDPGetArray((BYTE*)&DHCPClient.tempIPAddress, sizeof(DHCPClient.tempIPAddress));
			DHCPClient.validValues.bits.IPAddress = 1;
		}

		// Jump to DHCP options (ignore htype, hlen, hops, xid, secs, flags, 
		// ciaddr, siaddr, giaddr, padding part of chaddr, sname, file, magic 
		// cookie fields)
		UDPSetRxBuffer(240);

		lbDone = FALSE;
		do
		{
			// Get the Option number
			// Break out eventually in case if this is a malformed 
			// DHCP message, ie: missing DHCP_END_OPTION marker
			if(!UDPGet(&v))
			{
				lbDone = TRUE;
				break;
			}

			switch(v)
			{
				case DHCP_MESSAGE_TYPE:
					UDPGet(&v);                         // Skip len
					// Len must be 1.
					if ( v == 1u )
					{
						UDPGet(&type);                  // Get type

						// Throw away the packet if we know we don't need it (ie: another offer when we already have one)
						if(DHCPClient.flags.bits.bOfferReceived && (type == DHCP_OFFER_MESSAGE))
						{
							goto UDPInvalid;
						}
					}
					else
						goto UDPInvalid;
					break;

				case DHCP_SUBNET_MASK:
					UDPGet(&v);                     // Skip len
					// Len must be 4.
					if ( v == 4u )
					{
						// Check to see if this is the first offer
						if(DHCPClient.flags.bits.bOfferReceived)
						{
							// Discard offered IP mask, we already have an offer
							for ( i = 0; i < 4u; i++ )
								UDPGet(&v);
						}
						else
						{
							UDPGetArray((BYTE*)&DHCPClient.tempMask, sizeof(DHCPClient.tempMask));
							DHCPClient.validValues.bits.Mask = 1;
						}
					}
					else
						goto UDPInvalid;
					break;

				case DHCP_ROUTER:
					UDPGet(&j);
					// Len must be >= 4.
					if ( j >= 4u )
					{
						// Check to see if this is the first offer
						if(DHCPClient.flags.bits.bOfferReceived)
						{
							// Discard offered Gateway address, we already have an offer
							for ( i = 0; i < 4u; i++ )
								UDPGet(&v);
						}
						else
						{
							UDPGetArray((BYTE*)&DHCPClient.tempGateway, sizeof(DHCPClient.tempGateway));
							DHCPClient.validValues.bits.Gateway = 1;
						}
					}
					else
						goto UDPInvalid;

					// Discard any other router addresses.
					j -= 4;
					while(j--)
						UDPGet(&v);
					break;

				#if defined(STACK_USE_DNS)
				case DHCP_DNS:
					UDPGet(&j);
					// Len must be >= 4.
					if(j < 4u)
						goto UDPInvalid;

					// Check to see if this is the first offer
					if(!DHCPClient.flags.bits.bOfferReceived)
					{
						UDPGetArray((BYTE*)&DHCPClient.tempDNS, sizeof(DHCPClient.tempDNS));
						DHCPClient.validValues.bits.DNS = 1;
						j -= 4;
					}

					// Len must be >= 4 for a secondary DNS server address
					if(j >= 4u)
					{
						// Check to see if this is the first offer
						if(!DHCPClient.flags.bits.bOfferReceived)
						{
							UDPGetArray((BYTE*)&DHCPClient.tempDNS2, sizeof(DHCPClient.tempDNS2));
							DHCPClient.validValues.bits.DNS2 = 1;
							j -= 4;
						}
					}

					// Discard any other DNS server addresses
					while(j--)
						UDPGet(&v);
					break;
				#endif

					//            case DHCP_HOST_NAME:
					//                UDPGet(&j);
					//                // Len must be >= 4.
					//                if(j < 1u)
					//					goto UDPInvalid;
					//
					//				// Check to see if this is the first offer
					//				if(DHCPFlags.bits.bOfferReceived)
					//				{
					//			        // Discard offered host name, we already have an offer
					//	                while(j--)
					//	                    UDPGet(&v);
					//				}
					//				else
					//				{
					//					for(i = 0; j, i < sizeof(tempHostName); i++, j--)
					//					{
					//						UDPGet(&tempHostName[i]);
					//					}
					//					while(j--)
					//					{
					//						UDPGet(&v);
					//					}
					//					ValidValues.bits.HostName = 1;
					//				}
					//
					//                break;

				case DHCP_SERVER_IDENTIFIER:
					UDPGet(&v);                         // Get len
					// Len must be 4.
					if ( v == 4u )
					{
						UDPGet(&(((BYTE*)&tempServerID)[3]));   // Get the id
						UDPGet(&(((BYTE*)&tempServerID)[2]));
						UDPGet(&(((BYTE*)&tempServerID)[1]));
						UDPGet(&(((BYTE*)&tempServerID)[0]));
					}
					else
						goto UDPInvalid;
					break;

				case DHCP_END_OPTION:
					lbDone = TRUE;
					break;

				case DHCP_IP_LEASE_TIME:
					UDPGet(&v);                         // Get len
					// Len must be 4.
					if ( v == 4u )
					{
						// Check to see if this is the first offer
						if(DHCPClient.flags.bits.bOfferReceived)
						{
							// Discard offered lease time, we already have an offer
							for ( i = 0; i < 4u; i++ )
								UDPGet(&v);
						}
						else
						{
							UDPGet(&(((BYTE*)(&DHCPClient.dwLeaseTime))[3]));
							UDPGet(&(((BYTE*)(&DHCPClient.dwLeaseTime))[2]));
							UDPGet(&(((BYTE*)(&DHCPClient.dwLeaseTime))[1]));
							UDPGet(&(((BYTE*)(&DHCPClient.dwLeaseTime))[0]));

							// In case if our clock is not as accurate as the remote 
							// DHCP server's clock, let's treat the lease time as only 
							// 96.875% of the value given
							DHCPClient.dwLeaseTime -= DHCPClient.dwLeaseTime>>5;
						}
					}
					else
						goto UDPInvalid;
					break;

				default:
					// Ignore all unsupport tags.
					UDPGet(&j);                     // Get option len
					while( j-- )                    // Ignore option values
						UDPGet(&v);
			}
		} while( !lbDone );
	}