📄 dhcp.c
字号:
| |
| 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 + -