⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhcp.c

📁 单片机c语言程序设计100例--基于PIC+PROTEUS
💻 C
📖 第 1 页 / 共 2 页
字号:
   |                                                               |
   |                          sname   (64)                         |
   +---------------------------------------------------------------+
   |                                                               |
   |                          file    (128)                        |
   +---------------------------------------------------------------+
   |                                                               |
   |                          options (312)                        |
   +---------------------------------------------------------------+

 ********************************************************************/
static BYTE _DHCPReceive(void)
{
    BYTE v;
    BYTE i, j;
    BYTE type;
    BOOL lbDone;
    DWORD_VAL tempServerID;


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

    UDPGet(&v);                             // op
    
    // Make sure this is BOOT_REPLY.
    if ( v == BOOT_REPLY )
    {
        // Discard htype, hlen, hops, xid, secs, flags, ciaddr.
        for ( i = 0; i < 15u; i++ )
            UDPGet(&v);

		// Check to see if this is the first offer
		if(DHCPState.bits.bOfferReceived)
		{
	        // Discard offered IP address, we already have an offer
	        for ( i = 0; i < 4u; i++ )
	            UDPGet(&v);
		}
		else
		{
	        // Save offered IP address until we know for sure that we have it.
	        UDPGet(&tempIPAddress.v[0]);
	        UDPGet(&tempIPAddress.v[1]);
	        UDPGet(&tempIPAddress.v[2]);
	        UDPGet(&tempIPAddress.v[3]);
			ValidValues.bits.IPAddress = 1;
		}

        // Ignore siaddr, giaddr
        for ( i = 0; i < 8u; i++ )
            UDPGet(&v);

        // Check to see if chaddr (Client Hardware Address) belongs to us.
        for ( i = 0; i < 6u; i++ )
        {
            UDPGet(&v);
            if ( v != AppConfig.MyMACAddr.v[i])
                goto UDPInvalid;
        }


        // Ignore part of chaddr, sname, file, magic cookie.
        for ( i = 0; i < 206u; i++ )
            UDPGet(&v);

        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(DHCPState.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(DHCPState.bits.bOfferReceived)
					{
				        // Discard offered IP mask, we already have an offer
				        for ( i = 0; i < 4u; i++ )
				            UDPGet(&v);
					}
					else
					{
	                    UDPGet(&tempMask.v[0]);
	                    UDPGet(&tempMask.v[1]);
	                    UDPGet(&tempMask.v[2]);
	                    UDPGet(&tempMask.v[3]);
						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(DHCPState.bits.bOfferReceived)
					{
				        // Discard offered Gateway address, we already have an offer
				        for ( i = 0; i < 4u; i++ )
				            UDPGet(&v);
					}
					else
					{
	                    UDPGet(&tempGateway.v[0]);
	                    UDPGet(&tempGateway.v[1]);
	                    UDPGet(&tempGateway.v[2]);
	                    UDPGet(&tempGateway.v[3]);
						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 )
                {
					// Check to see if this is the first offer
					if(DHCPState.bits.bOfferReceived)
					{
				        // Discard offered DNS server address, we already have an offer
				        for ( i = 0; i < 4u; i++ )
				            UDPGet(&v);
					}
					else
					{
	                    UDPGet(&tempDNS.v[0]);
	                    UDPGet(&tempDNS.v[1]);
	                    UDPGet(&tempDNS.v[2]);
	                    UDPGet(&tempDNS.v[3]);
						ValidValues.bits.DNS = 1;
					}
                }
                else
                    goto UDPInvalid;

                // Discard any other DNS server addresses
                j -= 4;
                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(DHCPState.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(&tempServerID.v[3]);   // Get the id
                    UDPGet(&tempServerID.v[2]);
                    UDPGet(&tempServerID.v[1]);
                    UDPGet(&tempServerID.v[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(DHCPState.bits.bOfferReceived)
					{
				        // Discard offered lease time, we already have an offer
				        for ( i = 0; i < 4u; i++ )
				            UDPGet(&v);
					}
					else
					{
	                    UDPGet(&DHCPLeaseTime.v[3]);
	                    UDPGet(&DHCPLeaseTime.v[2]);
	                    UDPGet(&DHCPLeaseTime.v[1]);
	                    UDPGet(&DHCPLeaseTime.v[0]);

	                    // Due to possible timing delays, consider actual lease
	                    // time less by half hour.
	                    if ( DHCPLeaseTime.Val > HALF_HOUR )
	                        DHCPLeaseTime.Val = DHCPLeaseTime.Val - HALF_HOUR;
					}
                }
                else
                    goto UDPInvalid;
                break;

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

    // If this is an OFFER message, remember current server id.
    if ( type == DHCP_OFFER_MESSAGE )
    {
        DHCPServerID.Val = tempServerID.Val;
		DHCPState.bits.bOfferReceived = TRUE;
    }
    else
    {
        // For other types of messages, make sure that received
        // server id matches with our previous one.
        if ( DHCPServerID.Val != tempServerID.Val )
            type = DHCP_UNKNOWN_MESSAGE;
    }

    UDPDiscard();                             // We are done with this packet
    return type;

UDPInvalid:
    UDPDiscard();
    return DHCP_UNKNOWN_MESSAGE;

}





static void _DHCPSend(BYTE messageType)
{
    BYTE i;


    UDPPut(BOOT_REQUEST);                       // op
    UDPPut(HW_TYPE);                            // htype
    UDPPut(LEN_OF_HW_TYPE);                     // hlen
    UDPPut(0);                                  // hops
    UDPPut(0x12);                               // xid[0]
    UDPPut(0x23);                               // xid[1]
    UDPPut(0x34);                               // xid[2]
    UDPPut(0x56);                               // xid[3]
    UDPPut(0);                                  // secs[0]
    UDPPut(0);                                  // secs[1]
    UDPPut(0x80);                               // flags[0] with BF set
    UDPPut(0);                                  // flags[1]

    // If this is DHCP REQUEST message, use previously allocated IP address.
#if 0
    if ( messageType == DHCP_REQUEST_MESSAGE )
    {
        UDPPut(tempIPAddress.v[0]);
        UDPPut(tempIPAddress.v[1]);
        UDPPut(tempIPAddress.v[2]);
        UDPPut(tempIPAddress.v[3]);
    }
    else
#endif
    {
        UDPPut(0x00);
        UDPPut(0x00);
        UDPPut(0x00);
        UDPPut(0x00);
    }

    // Set yiaddr, siaddr, giaddr as zeros,
    for ( i = 0; i < 12u; i++ )
        UDPPut(0x00);

    // Load chaddr - Client hardware address.
    UDPPut(AppConfig.MyMACAddr.v[0]);
    UDPPut(AppConfig.MyMACAddr.v[1]);
    UDPPut(AppConfig.MyMACAddr.v[2]);
    UDPPut(AppConfig.MyMACAddr.v[3]);
    UDPPut(AppConfig.MyMACAddr.v[4]);
    UDPPut(AppConfig.MyMACAddr.v[5]);

    // Set chaddr[6..15], sname and file as zeros.
    for ( i = 0; i < 202u; i++ )
        UDPPut(0);

    // Load magic cookie as per RFC 1533.
    UDPPut(99);
    UDPPut(130);
    UDPPut(83);
    UDPPut(99);

    // Load message type.
    UDPPut(DHCP_MESSAGE_TYPE);
    UDPPut(DHCP_MESSAGE_TYPE_LEN);
    UDPPut(messageType);

	if(messageType == DHCP_DISCOVER_MESSAGE)
	{
		// Reset offered flag so we know to act upon the next valid offer
		DHCPState.bits.bOfferReceived = FALSE;
	}


    if ( messageType != DHCP_DISCOVER_MESSAGE && tempIPAddress.Val != 0x0000u )
    {
         // DHCP REQUEST message may include server identifier,
         // to identify the server we are talking to.
         // DHCP ACK may include it too.  To simplify logic,
         // we will include server identifier in DHCP ACK message too.
         // _DHCPReceive() would populate "serverID" when it
         // receives DHCP OFFER message. We will simply use that
         // when we are replying to server.
         // If this is a renwal request, do not include server id.
         UDPPut(DHCP_SERVER_IDENTIFIER);
         UDPPut(DHCP_SERVER_IDENTIFIER_LEN);
         UDPPut(DHCPServerID.v[3]);
         UDPPut(DHCPServerID.v[2]);
         UDPPut(DHCPServerID.v[1]);
         UDPPut(DHCPServerID.v[0]);
     }

    // Load our interested parameters
    // This is hardcoded list.  If any new parameters are desired,
    // new lines must be added here.
    UDPPut(DHCP_PARAM_REQUEST_LIST);
    UDPPut(DHCP_PARAM_REQUEST_LIST_LEN);
    UDPPut(DHCP_SUBNET_MASK);
    UDPPut(DHCP_ROUTER);
	UDPPut(DHCP_DNS);
	UDPPut(DHCP_HOST_NAME);

     // Add requested IP address to DHCP Request Message
    if ( messageType == DHCP_REQUEST_MESSAGE )
    {
        UDPPut(DHCP_PARAM_REQUEST_IP_ADDRESS);
        UDPPut(DHCP_PARAM_REQUEST_IP_ADDRESS_LEN);

        UDPPut(tempIPAddress.v[0]);
        UDPPut(tempIPAddress.v[1]);
        UDPPut(tempIPAddress.v[2]);
        UDPPut(tempIPAddress.v[3]);
    }

    // Add any new paramter request here.

    // End of Options.
    UDPPut(DHCP_END_OPTION);

    UDPFlush();
}


#endif	//#if defined(STACK_USE_DHCP)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -