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

📄 dhcp.c

📁 基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7的BSP,操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:

    /* Set the DHCP state. */
    device->dev_addr.dev_dhcp_state = DHCP_REQUESTING_STATE;

    if( (found & ACCEPT_BIT) == ACCEPT_BIT )
    {
        retval = DHCP_Send_Request(ds_ptr, socketd, device);
        if( retval == NU_SUCCESS)
        {
            if ( DEV_Attach_IP_To_Device( dv_name, ds_ptr->dhcp_yiaddr,
                                          ds_ptr->dhcp_net_mask) != NU_SUCCESS)
            {
                NERRS_Log_Error( NERR_FATAL, __FILE__, __LINE__);
                retval = NU_DHCP_INIT_FAILED;

            }  /* if status */
            else
            {
                /* Set the DHCP state. */
                device->dev_addr.dev_dhcp_state = DHCP_BOUND_STATE;
                
                /* Set up the timer events that will renew the lease. */
                DHCP_Init_Timers(device);
            }

        } /*  If found */
    } /*  Accept Bit  */
    else
    {
         NERRS_Log_Error( NERR_FATAL, __FILE__, __LINE__);

         retval = NU_DHCP_REQUEST_FAILED;
    }

DHCP_Exit:

    if (socketd >= 0)
        NU_Close_Socket(socketd);
    
    NU_USER_MODE();
    return(retval);
} /* NU_Dhcp */


/******************************************************************************
* FUNCTION                                                 
*                                                          
*      DHCP_Send_Request                                   
*                                                          
* DESCRIPTION                                              
*                                                          
*    Send a DHCP Request message.                          
*                                                          
* INPUTS                                                   
*                                                          
*      ds_ptr                  Pointer to DHCP structure.  
*      socketd                 Socket descriptor.          
*      device                  Pointer to device structure.
*                                                          
* OUTPUTS                                                  
*                                                          
*      NU_SUCCESS                                          
*      NU_NO_BUFFERS                                       
*      NU_DHCP_INIT_FAILED                                 
*      NU_DHCP_REQUEST_FAILED                              
*                                                          
******************************************************************************/
static STATUS DHCP_Send_Request( DHCP_STRUCT *ds_ptr, INT socketd, 
                                 DV_DEVICE_ENTRY *device)
{
    INT                 i;
    INT32               delay, rand;
    INT                 found;
    STATUS              status;


    found = 0;

    /* The (i + 2) check is because the third element of the 
       TCP backoff array is used first and we don't want to 
       extend past the end of the backoff array. See it's use below. */
    for( i = 0; (i < RETRIES_COUNT) && ( (i + 2) < TCP_MAX_BACKOFFS); i++ )
    {

        /* Send the packet. */
        status = DHCP_Send(device, ds_ptr, DHCPREQUEST);

        if( status != NU_SUCCESS )
        {
            NERRS_Log_Error( NERR_FATAL, __FILE__, __LINE__);
            break;
        }

        /* Compute a delay between retransmissions of DHCP messages. RFC 2131 
           specifies that a randomized exponential backoff algorithm must be 
           used. The first retransmission should be at 4 seconds, then 8, then 
           16, etc., up to a max of 64. This value should be randomized by plus
           or minus a second. */

        /* Get a random number. */
        rand = UTL_Rand();

        /* Compute a number that is between 0 and SCK_Ticks_Per_Second. */
        delay = rand % SCK_Ticks_Per_Second;

        /* At this point we have a delay that is equal to some value between 
           0 and 1 second. Now an arbitrary bit has been chosen from the random 
           number. If this bit is set then change the sign of the delay. About 
           half the time we should end up with a negative number. */
        if (rand & 0x80)
            delay = (-delay);

        /* Here we make use of the TCP backoff array. This array looks like 
           {1, 2, 4, 8, 16, .... 64, 64,..}. The first value taken from this 
           array will be 4 (i+2). 4 will be multiplied by SCK_Ticks_Per_Second and 
           the original delay will be added to it. The original delay 
           will be a number of ticks that is in the range of -1 to +1 seconds. 
           The final delay computed will be between 3 and 5 seconds (4 +|- 1). */
        delay = (TCP_Backoff[i+2] * SCK_Ticks_Per_Second) + delay;

        found = DHCP_Process_ACK( socketd, ds_ptr, device, (UINT32)delay);
        if( found != 0 )
        {
            break;
        }

        found = 0;

    }

    if (found == 1)
        return NU_SUCCESS;
    else
        return NU_DHCP_REQUEST_FAILED;

} /* DHCP_Send_Request */

/**************************************************************************
* FUNCTION                                                               
*                                                                        
*      NU_Dhcp_Release                                                   
*                                                                        
* DESCRIPTION                                                            
*                                                                        
*      This function releases the address acquired by the NU_Dhcp        
*      function call.                                                    
*
* INPUTS                                                                 
*                                                                        
*      ds_ptr                         Pointer to DHCP Structure that     
*                                     contains data that can be obtained 
*                                     at the application layer.          
*      dv_name                        Pointer to Devices name.           
*                                                                        
* OUTPUTS                                                                
*                                                                        
*      NU_SUCCESS                                                        
*      NU_DHCP_INIT_FAILED                                               
*      NU_NO_BUFFERS                                                     
*                                                                        
**************************************************************************/

STATUS NU_Dhcp_Release( DHCP_STRUCT *ds_ptr, CHAR *dv_name)
{
    DV_DEVICE_ENTRY   *device;
    STATUS            status;
    NU_SUPERV_USER_VARIABLES

    if ((ds_ptr == NU_NULL) || (dv_name == NU_NULL))
        return (NU_INVALID_PARM);

    /* Switch to supervisor mode. */
    NU_SUPERVISOR_MODE();

    /* get a pointer to the interface structure. */
    device = DEV_Get_Dev_By_Name(dv_name);
    
    /* Was a valid device found? */
    if (!device || (device->dev_mtu < DHCP_MAX_HEADER_SIZE))
    {
        NU_USER_MODE();
        return (NU_DHCP_INIT_FAILED);
    }

    /* Go ahead and clear the IP address renewal and rebinding events. */
    UTL_Timerunset (DHCP_RENEW, (UINT32)device, (INT32)1);
    UTL_Timerunset (DHCP_REBIND, (UINT32)device, (INT32)1);

    /* Send the release message. */
    status = DHCP_Send(device, ds_ptr, DHCPRELEASE);

    if( status != NU_SUCCESS )
    {
        NERRS_Log_Error( NERR_FATAL, __FILE__, __LINE__);
        NU_USER_MODE();
        return(-1);
    }

    DEV_Detach_IP_From_Device(dv_name);
    
    NU_USER_MODE();
    return(0);
}  /* NU_Dhcp_Release */

/****************************************************************************
* FUNCTION                                                                   
*                                                                            
*      DHCP_Process_Offer                                                    
*                                                                            
* DESCRIPTION                                                                
*                                                                            
*      Process a DHCP offer 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 the device.                        
*      timeout                 Timeout value used for NU_Select.             
*                                                                            
* OUTPUTS                                                                    
*                                                                            
*      NU_SUCCESS                                                            
*      NU_NO_SOCK_MEMORY                                                     
*                                                                            
******************************************************************************/

static STATUS DHCP_Process_Offer( INT socketd, DHCP_STRUCT *ds_ptr, 
                                  DV_DEVICE_ENTRY *device, UINT32 timeout)
{
    INT32       ret;
    INT16       flen;
    INT16       found = 0;
    UINT32      vend_cookie;
    UINT8       *pt;
    DHCPLAYER   *dhcp_ptr;          /* DHCP uses a Bootp type struct */
    FD_SET      readfs;
    STATUS      status;
    struct addr_struct fromaddr;


    status = NU_Allocate_Memory(&System_Memory, (VOID **)&dhcp_ptr, IOSIZE,
                (UNSIGNED)NU_NO_SUSPEND);

    if (status != NU_SUCCESS)
    {
        NERRS_Log_Error( NERR_FATAL, __FILE__, __LINE__);
        return (NU_NO_SOCK_MEMORY);
    }

    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 *)dhcp_ptr, IOSIZE, 0, &fromaddr, &flen);

        if( ret < 0 )
        {
            NERRS_Log_Error( NERR_FATAL, __FILE__, __LINE__);
            break;
        }

        if( dhcp_ptr->dp_xid != ds_ptr->dhcp_xid )
            continue;
            
        /* At this point we are looking for a DHCP offer. If we did not get 
           one then move on to the next one. Add 4 to get past the cookie. */
        if (DHCP_Message_Type(dhcp_ptr->dp_vend + 4) != DHCPOFFER)
            continue;
        
        /* Validate the DHCPOFFER. */
        if(DHCP_Validate(ds_ptr, device->dev_net_if_name, dhcp_ptr) == 0 )
             continue;

        IP_ADDR_COPY(ds_ptr->dhcp_siaddr, dhcp_ptr->dp_siaddr.is_ip_addrs);
        IP_ADDR_COPY(ds_ptr->dhcp_giaddr, dhcp_ptr->dp_giaddr.is_ip_addrs);
        IP_ADDR_COPY(ds_ptr->dhcp_yiaddr, dhcp_ptr->dp_yiaddr.is_ip_addrs);

        memcpy(ds_ptr->dhcp_sname, dhcp_ptr->dp_sname, sizeof(ds_ptr->dhcp_sname) );
        memcpy(ds_ptr->dhcp_file, dhcp_ptr->dp_file, sizeof(ds_ptr->dhcp_file) );
        vend_cookie = GET32(dhcp_ptr->dp_vend, 0);

        /* test to see if cookie is a vendor cookie */
        if( vend_cookie == DHCP_COOKIE )
        {

⌨️ 快捷键说明

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