📄 dhcp.c
字号:
* DESCRIPTION
*
* Initialize the UDP header that encapsulates the DHCP message.
*
* INPUTS
*
* buf_ptr
* src
* dst
*
* OUTPUTS
*
* None.
*
******************************************************************************/
static VOID DHCP_Init_UDP_Layer(NET_BUFFER *buf_ptr, UINT32 src, UINT32 dst)
{
UDPLAYER HUGE *udp_pkt;
struct pseudotcp tcp_chk;
udp_pkt = (UDPLAYER *)(buf_ptr->data_ptr - sizeof(UDPLAYER));
/* Initialize the local and foreign port numbers. */
PUT16(udp_pkt, UDP_SRC_OFFSET, DHCP_Client_Port);
PUT16(udp_pkt, UDP_DEST_OFFSET, DHCP_Server_Port);
/* Set the total length. */
PUT16( udp_pkt, UDP_LENGTH_OFFSET,
(UINT16)(buf_ptr->mem_total_data_len + sizeof (UDPLAYER)) );
/* The checksum field should be cleared to zero before the checksum is
computed. */
PUT16(udp_pkt, UDP_CHECK_OFFSET, 0);
/* Point to the start of the UDP header. Update the size data length of
the whole chain and the data length for this buffer. */
buf_ptr->data_ptr -= sizeof(UDPLAYER);
buf_ptr->mem_total_data_len += sizeof(UDPLAYER);
buf_ptr->data_len += sizeof(UDPLAYER);
/* Calculate the UDP Checksum. */
tcp_chk.source = LONGSWAP(src);
tcp_chk.dest = LONGSWAP(dst);
tcp_chk.z = 0;
tcp_chk.proto = IP_UDP_PROT;
tcp_chk.tcplen = INTSWAP((UINT16)buf_ptr->mem_total_data_len);
PUT16(udp_pkt, UDP_CHECK_OFFSET, TLS_TCP_Check( (UINT16 *)&tcp_chk, buf_ptr) );
/* If a checksum of zero is computed it should be replaced with 0xffff. */
if (GET16(udp_pkt, UDP_CHECK_OFFSET) == 0)
PUT16(udp_pkt, UDP_CHECK_OFFSET, 0xFFFF);
} /* DHCP_Init_UDP_Layer */
/****************************************************************************
* FUNCTION
*
* DHCP_Init_IP_Layer
*
* DESCRIPTION
*
* Initialize the IP header that encapsulates the DHCP message.
*
* INPUTS
*
* buf_ptr
* ip_src
* ip_dest
*
* OUTPUTS
*
* None.
*
******************************************************************************/
static VOID DHCP_Init_IP_Layer(NET_BUFFER *buf_ptr, UINT32 ip_src, UINT32 ip_dest)
{
IPLAYER HUGE *ip_ptr;
INT16 hlen = sizeof (IPLAYER);
UINT32 length;
ip_ptr = (IPLAYER *)(buf_ptr->data_ptr - sizeof(IPLAYER));
/* Set the IP header length and the IP version. */
PUT8( ip_ptr, IP_VERSIONANDHDRLEN_OFFSET,
(UINT8)((hlen >> 2) | (IP_VERSION << 4)) );
/* Set to no fragments and don't fragment. */
/* ip_ptr->frags = INTSWAP(IP_DF); */
PUT16(ip_ptr, IP_FRAGS_OFFSET, 0);
/* Set the IP packet ID. */
PUT16(ip_ptr, IP_IDENT_OFFSET, 0);
/* Set the type of service. */
PUT8(ip_ptr, IP_SERVICE_OFFSET, 0);
length = buf_ptr->mem_total_data_len;
/* Set the total length (data and IP header) for this packet. */
PUT16(ip_ptr, IP_TLEN_OFFSET, (INT16)(length + hlen) );
/* Set the time to live */
PUT8(ip_ptr, IP_TTL_OFFSET, IP_TIME_TO_LIVE);
/* Set the protocol. */
PUT8(ip_ptr, IP_PROTOCOL_OFFSET, IP_UDP_PROT);
/* Fill in the destination and source IP addresses. */
PUT32(ip_ptr, IP_SRC_OFFSET, ip_src);
PUT32(ip_ptr, IP_DEST_OFFSET, ip_dest);
/* Compute the IP checksum. Note that the length expected by */
/* ipcheck is the length of the header in 16 bit half-words. */
PUT16(ip_ptr, IP_CHECK_OFFSET, 0);
PUT16(ip_ptr, IP_CHECK_OFFSET, TLS_IP_Check ((UINT16 *)ip_ptr, (UINT16)(hlen >> 1)) );
/* Set the buffer pointer to the IP Layer. */
buf_ptr->data_ptr -= sizeof(IPLAYER);
/* Add the IPLAYER to the total data length */
buf_ptr->mem_total_data_len += sizeof(IPLAYER);
/* Set the data length of the current packet. */
buf_ptr->data_len += sizeof(IPLAYER);
} /* DHCP_Init_IP_Layer */
/****************************************************************************
* FUNCTION
*
* DHCP_Validate
*
* DESCRIPTION
*
* Function decides if a DHCPOFFER packet should be accepted. An example is
* provided that verfifies the response is from the expected DHCP server.
* It is intended that this function will need to be modified for specific
* applications.
*
* INPUTS
*
* ds_ptr DHCP struct pointer.
* dv_name Device name of the current network card.
* dp DHCPLAYER structure pointer of current
* DHCPOFFER packet.
*
* OUTPUTS
*
* NU_TRUE Current DHCPOFFER packet is valid.
* NU_FALSE Not valid.
*
******************************************************************************/
INT DHCP_Validate(DHCP_STRUCT *ds_ptr, CHAR *dv_name, const DHCPLAYER *dp)
{
#if DHCP_VALIDATE_CALLBACK
UINT32 server_ip = 0xD0EFA80Dul;
/* stops compiler from complaining about unused varaibles. */
if( ds_ptr == 0 || dv_name == 0 || dp == 0 )
return(NU_FALSE);
/* Other items could be checked here but the user would have to */
/* parse the vendor options field of the DHCPOFFER packet. See */
/* RFC 2132. */
/*** Note: As of RFC 2132 the vendor option field is now variable ***/
/*** length and not 64 bytes in size. Your must look for a DHCP_END. **/
/* Does the DHCP server IP address match the address of the "trusted"
DHCP server. */
if (memcmp(&dp->dp_siaddr, &server_ip,4) == 0)
return(NU_TRUE);
else
return(NU_FALSE);
#else
/* Get rid of compiler warnings. These parameters probably will be used
when a user fleshes out this function. */
UNUSED_PARAMETER(ds_ptr);
UNUSED_PARAMETER(dv_name);
UNUSED_PARAMETER(dp);
return(NU_TRUE);
#endif
}
/****************************************************************************
* FUNCTION
*
* DHCP_Vendor_Options
*
* DESCRIPTION
*
* Function handles all vendor options returned by the DHCP server.
*
* INPUTS
*
* device
* opc Opcode for the vendor option.
* len Length of vendor option in bytes.
* opt_data Length of vendor option in bytes.
* ds_ptr Pointer to vendor option value.
*
* OUTPUTS
*
* If TRUE is returned by this function then NU_Dhcp function will stop
* processing vendor options, otherwise -1 is returned.
*
******************************************************************************/
static STATUS DHCP_Vendor_Options( DV_DEVICE_ENTRY *device, UINT8 opc, UINT16 len,
UINT8 *opt_data, DHCP_STRUCT *ds_ptr)
{
STATUS ret = 0;
#if (INCLUDE_DNS == NU_TRUE)
UINT8 ip_address[4];
#endif
/* Make sure we have a valied device pointer. */
if( device == NU_NULL )
return(-1);
/* As of RFC2131 and RFC2132 */
/* This switch contains all opcodes known as of the above RFC's. */
/* none or all opcodes could be returned by the DHCP server. */
switch( opc )
{
case DHCP_NETMASK:
IP_ADDR_COPY(ds_ptr->dhcp_net_mask, opt_data);
break;
case DHCP_TIME_OFFSET:
break;
case DHCP_ROUTE:
/* Set the default route. */
RTAB_Set_Default_Route( device, GET32(opt_data, 0),
(UINT16)(RT_UP | RT_GATEWAY));
IP_ADDR_COPY(ds_ptr->dhcp_giaddr, opt_data);
break;
case DHCP_TIME:
case DHCP_NAME_SERVER:
break;
case DHCP_DNS:
#if (INCLUDE_DNS == NU_TRUE)
/* We received an list of DNS server addresses. Add each in turn
to the Nucleus NET list of DNS servers. */
while(len)
{
IP_ADDR_COPY(ip_address, opt_data);
/* When renewing the lease the list of servers received will
likely be the same as the first list. So first attempt to
delete the server. This will prevent duplicate addresses
from appearing in the list. */
NU_Delete_DNS_Server (ip_address);
/* Adding to the end will insure that the first one received is
the closest to the head of the list. */
NU_Add_DNS_Server(ip_address, DNS_ADD_TO_END);
len -= 4;
opt_data += 4;
}
#endif
break;
case DHCP_LOG_SERVER:
case DHCP_COOKIE_SERVER:
case DHCP_LPR_SERVER:
case DHCP_IMPRESS_SERVER:
case DHCP_RESOURCE_SERVER:
case DHCP_HOSTNAME:
case DHCP_BOOT_FILE_SIZE:
case DHCP_MERIT_DUMP_FILE:
case DHCP_DOMAIN_NAME:
case DHCP_SWAP_SERVER:
case DHCP_ROOT_PATH:
case DHCP_EXTENSIONS_PATH:
break;
/* IP Layer Parameters per Host. */
case DHCP_IP_FORWARDING:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -