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

📄 dhcp.c

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