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

📄 dhcp.c

📁 基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7的BSP,操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
       then copy it to the buffer chain. Allocate the contiguous memory here. */
    status = NU_Allocate_Memory( &System_Memory, (VOID **)&pkt,
                                 sizeof(DHCPLAYER), NU_NO_SUSPEND);
    
    if (status != NU_SUCCESS)
        return (status);

    memset(pkt, 0, sizeof(DHCPLAYER) );

    pkt->dp_op      = BOOTREQUEST;      /* opcode, 1 octet */
    pkt->dp_htype   = HARDWARE_TYPE;    /* hardware type, 1 octet */
    pkt->dp_hlen    = DADDLEN;          /* hardware address length, 1 octet */
    pkt->dp_xid     = ds_ptr->dhcp_xid;
    pkt->dp_secs    = 0;
    
    if (device->dev_addr.dev_dhcp_state == DHCP_RENEW_STATE)
       pkt->dp_flags= 0;
    else     
       pkt->dp_flags= INTSWAP(DHCP_BROADCAST_FLAG); /* set broadcast flag. */

    /* Fill in the client's hardware address. */
    memcpy(pkt->dp_chaddr, ds_ptr->dhcp_mac_addr, DADDLEN);

    len = sizeof(pkt->dp_op) +
      sizeof(pkt->dp_htype) +
      sizeof(pkt->dp_hlen) +
      sizeof(pkt->dp_hops) +
      sizeof(pkt->dp_xid) +
      sizeof(pkt->dp_secs) +
      sizeof(pkt->dp_flags) +
      sizeof(pkt->dp_ciaddr) +
      sizeof(pkt->dp_yiaddr) +
      sizeof(pkt->dp_siaddr) +
      sizeof(pkt->dp_giaddr) +
      sizeof(pkt->dp_chaddr) +
      sizeof(pkt->dp_sname) +
      sizeof(pkt->dp_file);
    
    pt = pkt->dp_vend;
    PUT32(pt, 0, DHCP_COOKIE);
    pt += 4;
    *pt++ = DHCP_MSG_TYPE;
    *pt++ = 1;
    *pt++ = msg_type;
    *pt++ = DHCP_CLIENT_CLASS_ID;
    *pt++ = 7;
    *pt++ = HARDWARE_TYPE;
    *pt++ = ds_ptr->dhcp_mac_addr[0];
    *pt++ = ds_ptr->dhcp_mac_addr[1];
    *pt++ = ds_ptr->dhcp_mac_addr[2];
    *pt++ = ds_ptr->dhcp_mac_addr[3];
    *pt++ = ds_ptr->dhcp_mac_addr[4];
    *pt++ = ds_ptr->dhcp_mac_addr[5];
    len += 16;

    if (msg_type == DHCPDISCOVER) /* Building a Discover packet. */
    {
        /* Currently there are no special options that need to be added to a
           discover. */

    }
    else if (msg_type == DHCPRELEASE) /* Building a release packet. */
    {
        /* Fill in ciaddr. */
        PUT32(pkt->dp_ciaddr.is_ip_addrs, 0, device->dev_addr.dev_ip_addr);
    }
    else  /* Must be building a request packet. */
    {
        /* Only fill in ciaddr if in the renewing or rebinding state. */
        if ( (device->dev_addr.dev_dhcp_state == DHCP_RENEW_STATE) ||
             (device->dev_addr.dev_dhcp_state == DHCP_REBIND_STATE) )
              PUT32(pkt->dp_ciaddr.is_ip_addrs, 0, device->dev_addr.dev_ip_addr);

        /* Only send the DHCP_Requested IP address during the INIT state. */
        if (device->dev_addr.dev_dhcp_state == DHCP_REQUESTING_STATE)
        {
            *pt++ = DHCP_REQUEST_IP;
            *pt++ = 4;
            *pt++ = ds_ptr->dhcp_yiaddr[0];
            *pt++ = ds_ptr->dhcp_yiaddr[1];
            *pt++ = ds_ptr->dhcp_yiaddr[2];
            *pt++ = ds_ptr->dhcp_yiaddr[3];
            len += 6;
        }

        /* Only send the server ID option if in the INIT state. */
        if (device->dev_addr.dev_dhcp_state == DHCP_REQUESTING_STATE)
        {
            /* tell all servers that responded to the DHCPDISCOVER broadcast */
            /* that the following server has been selected. */
            *pt++ = DHCP_SERVER_ID;
            *pt++ = 4;
            *pt++ = ds_ptr->dhcp_siaddr[0];
            *pt++ = ds_ptr->dhcp_siaddr[1];
            *pt++ = ds_ptr->dhcp_siaddr[2];
            *pt++ = ds_ptr->dhcp_siaddr[3];
            len += 6;
        }

        if( ds_ptr->dhcp_opts )
        {
            /* The user wishes to make some specific requests as to which
               options the server should return. */
            /* Copy the application specified options. */
            memcpy(pt, ds_ptr->dhcp_opts, ds_ptr->dhcp_opts_len);
            pt += ds_ptr->dhcp_opts_len;
            len += ds_ptr->dhcp_opts_len;
        }
    }

    /* Mark the end of the options list. */
    *pt = DHCP_END;
    len++;

    /* Some DHCP servers (SUN Solaris) reject DHCP messages that are less than 
       300 bytes in length. Pad the message if necessary. */
    if (len < 300)
        len = 300;

    status = DHCP_Pkt_Copy((UINT8 *)pkt, buf_ptr, len);

    NU_Deallocate_Memory(pkt);

    if (status != NU_SUCCESS)
        return (NU_DHCP_INIT_FAILED);
    else
        return (NU_SUCCESS);

} /* DHCP_Init_DHCP_Layer */


/****************************************************************************
* FUNCTION                                                                   
*                                                                            
*      DHCP_Pkt_Copy                                                         
*                                                                            
* DESCRIPTION                                                                
*                                                                            
*    Copy a DHCP message into a Nucleus NET buffer chain.                    
*                                                                            
* INPUTS                                                                     
*                                                                            
*      buffer                                                                
*      buf_ptr                                                               
*      length                                                                
*                                                                            
* OUTPUTS                                                                    
*                                                                            
*      NU_SUCCESS              Success.                                      
*      -1                      Failure.                                      
*                                                                            
******************************************************************************/
static STATUS DHCP_Pkt_Copy(UINT8 *buffer, NET_BUFFER *buf_ptr, INT length)
{
    INT         current_size, total_size = length;
    NET_BUFFER  *next_buf;

    /* Point to where the DHCP packet should begin. */
    buf_ptr->data_ptr = buf_ptr->mem_parent_packet + NET_MAX_UDP_HEADER_SIZE;
   
    /*  Chain the DHCP Request Packet */
    if (total_size > NET_PARENT_BUFFER_SIZE)
    {
       current_size = NET_PARENT_BUFFER_SIZE - NET_MAX_UDP_HEADER_SIZE;
       total_size =   total_size - current_size;
    }
    else
    {
       current_size =  total_size;
       total_size = 0;
    }

    /*  Copy DHCP Packet into first Buffer */
    memcpy(buf_ptr->data_ptr, buffer, (unsigned int)current_size);
    buf_ptr->data_len = current_size;
    buf_ptr->mem_total_data_len = length;

    /* Point to fresh data. */
    buffer += current_size;

    /* Point to the next buffer is there is one.  */
    next_buf = buf_ptr->next_buffer;

    /*  Check to make sure there is data to store in the mem_packet */
    while (total_size && next_buf)
    {
        /* Determine how much data can be copied to the next buffer. */                
        if (total_size > NET_MAX_BUFFER_SIZE)
            current_size = NET_MAX_BUFFER_SIZE;
        else
            current_size = total_size;

        total_size -= current_size;

        /*  Copy the remaining data in the chaining packets  */
        memcpy(next_buf->mem_packet, buffer, (unsigned int)current_size);

        /*  Set the Data pointer to the remainder of the packets.  */
        next_buf->data_ptr = next_buf->mem_packet;
        next_buf->next = NU_NULL;
        next_buf->data_len = current_size;

        /* Point to the next buffer is there is one.  */
        buffer = buffer + current_size;

        /* Point to the next buffer in the chain. */
        next_buf = next_buf->next_buffer;
    }

    /* When the original buffer chain was aloocated it was done so assuming 
       that a max DHCP message would be built. However, this is unlikely. 
       If there are any unused buffers in the chain then free them. The main 
       reason for doing this is incase the driver is not designed to handle a
       buffer chain that contains empty buffers. */
    for (next_buf = buf_ptr; next_buf; next_buf = next_buf->next_buffer)
    {
        /* If there is a buffer after the current one and that buffer contains 
           no data then free that buffer and any that follow it. */
        if (next_buf->next_buffer && (next_buf->next_buffer->data_len == 0))
        {
            MEM_One_Buffer_Chain_Free (next_buf->next_buffer, 
                                       &MEM_Buffer_Freelist);
            next_buf->next_buffer = NU_NULL;
        }
    }            

    /* At this point total_size should be 0. If it is not 0 then something
       has gone wrong. */
    if(total_size)
        return NU_DHCP_INIT_FAILED;
    else
        return NU_SUCCESS;

} /* DHCP_Pkt_Copy */

/******************************************************************************
* FUNCTION                                                                   
*                                                                            
*     DHCP_Send                                                              
*                                                                            
* DESCRIPTION                                                                
*                                                                            
*    Send a DHCP Message.                                                    
*                                                                            
* INPUTS                                                                     
*                                                                            
*      buf_ptr                                                               
*      int_face                                                              
*      dest_ip                                                               
*                                                                            
* OUTPUTS                                                                    
*                                                                            
*      NU_SUCCESS                                                            
*      -1                      Fail.                                         
*                                                                            
******************************************************************************/
static STATUS DHCP_Send( DV_DEVICE_ENTRY *device, DHCP_STRUCT *ds_ptr, UINT8 msg_type)
{
    STATUS              status;
    INT32               flags;
    SCK_SOCKADDR_IP     sa;
    NET_BUFFER          *buf_ptr;
    IPLAYER   HUGE      *ip_ptr;

    /* build the first DHCP discovery message */
    if ((status = DHCP_Build_Message(&buf_ptr, ds_ptr, device, msg_type)) != NU_SUCCESS)
        return status;

    ip_ptr = (IPLAYER *)(buf_ptr->data_ptr);
    
    /*  Set up MAC layer  */
    sa.sck_family = SK_FAM_IP;
    sa.sck_len = sizeof (sa);
    sa.sck_addr = GET32(ip_ptr, IP_DEST_OFFSET);

    /* Grab the semaphore because we are about to change the interface
       that the DHCP request will be sent over. */
    NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);

    /* The device will not send packets until an IP address is attached.
           Temporarily trick it into thinking an IP address is attached so this
           request can be sent.  Then set it back. */
    flags = device->dev_flags;
    device->dev_flags |= (DV_UP | DV_RUNNING);

    /* Send the packet. */
    status = (*(device->dev_output)) ( buf_ptr, device, &sa, NU_NULL );
    device->dev_flags = flags;

    NU_Release_Semaphore(&TCP_Resource);

    return status;

} /* DHCP_Send */

/****************************************************************************
* FUNCTION                                                                   
*                                                                            
*      DHCP_Init_UDP_Layer                                                   
*                                                                            

⌨️ 快捷键说明

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