Lwip之如何动态更改IP地址

  • Post author:
  • Post category:其他


**



如何重新设置一个网卡的IP地址

**

当内核基于某个IP地址运行一段时间后,该IP地址会在内核中留下许多足迹:ARP中会有该IP对应的缓存表项;Tcp连接控制块也会记录该IP地址。这时如果要重新设IP,不能以新的IP地址来调用内核初始化函(InitLwip),因为内核基于旧IP分配的资源并没有得到释放,严重的情况下,可能会导致内存访问错误,系统跑飞等现象。

网络接口管理函数中,有几个函数相当的重要,他们负责控制和维护网卡的状态,这些函数名称及功能如下表所示。其中netif_set_addr用于重设网卡的IP、网关和子网掩码三个地址,本质上它是通过分别调用netif_set_ipaddr、netif_set_gw、netif_set_mask三个函数来完成的。netif_set_up和netif_set_down为网卡启用和禁用网卡。从内核实现上看,禁用网卡会使ARP层清楚旧IP地址对的ARP缓存表项,而函数netif_set_ipaddr重新设置IP地址前,会将旧IP地址相关的所有Tcp连接的控制块全部删除,这样就保证了不会再有连接使用旧的IP地址发送数据。

注意,在重设IP地址的这种情况下,应用程序的连接自然也会被重置,内核会通知这种连接错误给应用程序,应用程序必须能检测并处理这种错误,并在适当地时候重新启动连接。

函数名称 功能
netif_add 向内核注册一个网络接口,设置网卡相关地址,并初始化
netif_remove 向内核注销一个网络接口
netif_set_default 设置系统默认网络接口
netif_set_addr 重新设置网络接口的IP地址、网关地址和子网掩码
netif_set_ipaddr 重新设置网络接口的IP地址
netif_set_gw 重新设置网络接口的网关地址
netif_set_netmask 重新设置网络接口的子网掩码
netif_set_up 启用网卡
netif_set_down 禁用网卡
netif_set_link_up 网卡底层打开,表示网卡已经可正常进行链路数据的收发
netif_set_link_down 网卡底层关闭,表示网卡不能再继续接收链路数据
void NetConfigUpdate(NETCONFIGMESG* sLocalMesg)
{
    int i;
    err_t err;
    struct ip_addr ip_update;
    struct ip_addr Mask_update;
    struct ip_addr GW_updata;

    IP4_ADDR(&ip_update,sLocalMesg->aSrcIP[0],sLocalMesg->aSrcIP[1],
            sLocalMesg->aSrcIP[2],sLocalMesg->aSrcIP[3]);
    IP4_ADDR(&Mask_update, sLocalMesg->aNetMask[0], sLocalMesg->aNetMask[1],
            sLocalMesg->aNetMask[2], sLocalMesg->aNetMask[3]);
    IP4_ADDR(&GW_updata, sLocalMesg->aGateWay[0], sLocalMesg->aGateWay[1],
            sLocalMesg->aGateWay[2], sLocalMesg->aGateWay[3]);

    u_byLocalIP[0]=sLocalMesg->aSrcIP[0];
    u_byLocalIP[1]=sLocalMesg->aSrcIP[1];
    u_byLocalIP[2]=sLocalMesg->aSrcIP[2];
    u_byLocalIP[3]=sLocalMesg->aSrcIP[3];

    for(i = 0; i < LWIP_MAX_CONNECT; i++)
    {
        if(u_sTcp_pcb[i] != NULL)
        {
            err = tcp_close(u_sTcp_pcb[i]);
            if(err == ERR_OK)
                u_sTcp_pcb[i] = NULL;
        }
    }
    netif_set_down(&u_sNetif); //先禁用网卡

    netif_set_gw(&u_sNetif, &GW_updata);        //重新设置网关地址
    netif_set_netmask(&u_sNetif, &Mask_update); //重新设置子网掩码
    netif_set_ipaddr(&u_sNetif, &ip_update);    //重新设置IP地址
//  netif_set_addr(&u_sNetif, &ip_update, &Mask_update, &GW_updata);

    netif_set_up(&u_sNetif);  //启用网卡
}



版权声明:本文为zhaozhiyuan111原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。