📄 dhcp.c
字号:
/* Now loop through vendor options, At this point the only option
we are interested in is the DHCP_SERVER_ID. RFC 2131 recommends
using the configuration parameters from the ACK rather than the
offer. */
pt = dhcp_ptr->dp_vend;
pt += 4; /* move past cookie */
for( ;*pt != DHCP_END; )
{
/* The only option we are interested in at this point is the
server ID. */
if (*pt == DHCP_SERVER_ID)
{
/* Step past the option type and option length. */
pt += 2;
/* Return the type of the DHCP message. */
IP_ADDR_COPY(ds_ptr->dhcp_siaddr, pt);
found = 1;
break;
}
/* If it is a PAD option just step past it. */
else if( *pt == DHCP_PAD ) /* move past PAD bytes */
{
pt++;
continue;
}
/* Step past any other options. */
else
{
/* First step past the option type. */
pt++;
/* Now step past the length of the option and the value. */
pt += (*pt + 1);
}
}
}
} while( found == 0 );
NU_Deallocate_Memory(dhcp_ptr);
return(found);
} /* DHCP_Process_Offer */
/****************************************************************************
* FUNCTION
*
* DHCP_Process_ACK
*
* DESCRIPTION
*
* Process a DHCP ACK message.
*
* INPUTS
*
* socketd Socket Descriptor to retrieve data from.
* ds_ptr Pointer to DHCP Structure that contains
* data that can be obtained at the
* application layer.
* device Pointer to device structure
* timeout Timeout value used for NU_Select.
*
* OUTPUTS
*
* STATUS Set to a 1 if Acknowledgement found, else
* returns a 0.
*
******************************************************************************/
static STATUS DHCP_Process_ACK( INT socketd, DHCP_STRUCT *ds_ptr,
DV_DEVICE_ENTRY *device, UINT32 timeout)
{
INT32 ret;
INT16 flen;
INT16 found = 0;
UINT8 *pt;
DHCPLAYER *inbp; /* DHCP uses a Bootp type struct */
FD_SET readfs;
struct addr_struct fromaddr;
UINT8 opcode;
INT16 length;
if (NU_Allocate_Memory(&System_Memory, (VOID **)&inbp, IOSIZE,
(UNSIGNED)NU_NO_SUSPEND) != NU_SUCCESS)
{
return 0;
}
do
{
NU_FD_Init(&readfs);
NU_FD_Set(socketd, &readfs);
/* Wait for a response to arrive. We are only interested in arriving
packets so the 3rd and 4th parameters are not needed. */
ret = NU_Select(NSOCKETS, &readfs, NU_NULL, NU_NULL, timeout);
if( ret == NU_NO_DATA )
break;
if(NU_FD_Check(socketd, &readfs) == NU_FALSE)
break;
fromaddr.family = NU_FAMILY_IP;
fromaddr.port = 0;
ret = NU_Recv_From(socketd, (CHAR *)inbp, IOSIZE,0,&fromaddr, &flen);
if( ret < 0 )
{
NERRS_Log_Error( NERR_FATAL, __FILE__, __LINE__);
break;
}
/* See if this message is returning a response to the message I sent */
if( inbp->dp_xid != ds_ptr->dhcp_xid )
continue;
/* test to see if cookie is a vendor cookie */
if( GET32(inbp->dp_vend, 0) != DHCP_COOKIE )
continue;
/* At this point we are only interested in receiving a DHCP ACK.
Make sure that is what we have received. The 4 is added to get past
the cookie. */
if (DHCP_Message_Type(inbp->dp_vend + 4) != DHCPACK)
break;
found = 1;
/* Now loop thur vendor options, passing them to user call */
/* back function. */
pt = inbp->dp_vend;
pt += 4; /* move past cookie */
for( ;*pt != DHCP_END; )
{
if( *pt == DHCP_PAD ) /* move past PAD bytes */
{
pt++;
continue;
}
opcode = *pt++; /* save opcode */
length = *pt++; /* save length */
/* Process the options in the message. */
DHCP_Vendor_Options(device, opcode, (UINT16)length, pt, ds_ptr);
pt += length;
}
} while( found == 0 );
NU_Deallocate_Memory(inbp);
return(found);
} /* DHCP_Process_ACK */
/**************************************************************************
* FUNCTION
*
* DHCP_Build_Message
*
* DESCRIPTION
*
* This function handles the initing of the DHCP packet.
*
* INPUTS
*
* return_buf This is a pointer to the buffer that the
* DHCP message is built in. It is undefined
* upon function entry. It will be set to
* point to a buffer upon exit.
* ds_ptr Pointer to DHCP Structure that contains
* data that is provide by the application.
* device Pointer to device structure..
* msg_type Type of DHCP message to build.
*
* OUTPUTS
*
* NU_SUCCESS
* NU_DHCP_INIT_FAILED
*
**************************************************************************/
static STATUS DHCP_Build_Message( NET_BUFFER **return_buf, DHCP_STRUCT *ds_ptr,
DV_DEVICE_ENTRY *device, UINT8 msg_type)
{
STATUS status;
STATUS retval = NU_SUCCESS;
NET_BUFFER *buf_ptr;
UINT32 ip_src, ip_dst;
/* Allocate a Nucleus NET buffer chain to put the DHCP discover packet in. */
buf_ptr = MEM_Buffer_Chain_Dequeue(&MEM_Buffer_Freelist, DHCP_MAX_HEADER_SIZE);
if (buf_ptr != NU_NULL)
{
/* After the packet is sent deallocate the buffer to the DHCP List. */
buf_ptr->mem_dlist = &MEM_Buffer_Freelist;
buf_ptr->data_len = 0;
buf_ptr->mem_total_data_len = 0;
/* build the first DHCP discovery message */
status = DHCP_Init_DHCP_Layer(buf_ptr, ds_ptr, device, msg_type);
if (status == NU_SUCCESS)
{
switch (device->dev_addr.dev_dhcp_state)
{
case DHCP_RENEW_STATE :
case DHCP_BOUND_STATE :
ip_src = device->dev_addr.dev_ip_addr;
ip_dst = device->dev_addr.dev_dhcp_server_addr;
break;
case DHCP_REBIND_STATE :
ip_src = device->dev_addr.dev_ip_addr;
ip_dst = IP_ADDR_BROADCAST;
/* The request will be broadcasted. */
buf_ptr->mem_flags |= NET_BCAST;
break;
default :
/* This is most likely the requesting state. */
ip_src = IP_ADDR_ANY;
ip_dst = IP_ADDR_BROADCAST;
/* The request will be broadcasted. */
buf_ptr->mem_flags |= NET_BCAST;
break;
}
DHCP_Init_UDP_Layer(buf_ptr, ip_src, ip_dst);
DHCP_Init_IP_Layer(buf_ptr, ip_src, ip_dst);
}
else
{
/* DHCP_Init_DHCP_Layer failed. Free the buffer and return the
reason for the failure.*/
retval = status;
MEM_One_Buffer_Chain_Free (buf_ptr, &MEM_Buffer_Freelist);
}
}
else
{
retval = NU_NO_BUFFERS;
}
*return_buf = buf_ptr;
return retval;
} /* DHCP_Build_Message */
/**************************************************************************
*
*FUNCTION
*
* DHCP_Init_DHCP_Layer
*
*DESCRIPTION
*
* Initalize the DHCP layer of the message.
*
*INPUTS
*
* buf_ptr Pointer to the buffer in which the
* DHCP message is being built.
* ds_ptr Pointer to DHCP Structure that contains
* data that is provide by the application.
* device Pointer to the device for which we are trying
* to acquire an IP address.
* msg_type Type of DHCP message being built (discover,
* request, release).
*
*OUTPUTS
*
* NU_SUCCESS upon successful completion a negative value otherwise.
*
**************************************************************************/
static STATUS DHCP_Init_DHCP_Layer( NET_BUFFER *buf_ptr, DHCP_STRUCT *ds_ptr,
DV_DEVICE_ENTRY *device, UINT8 msg_type)
{
INT len;
UINT8 *pt;
STATUS status;
DHCPLAYER *pkt;
/* The size of the Nucleus NET buffer chains are user configurable. This
makes it difficult build the DHCP packet in the Nucleus NET buffer chain.
To avoid these complexities build the buffer in contiguous memory and
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -