LWIP2.1.3网络接口管理netif源

LWIP网络接口概述

ethernetif.c 是lwip的接口文件  即:网卡文件

1、lwIP协议栈支持多种不同的网络接口(网卡),

2、lwIP对网卡统一的接口

3、底层的实现需要用户自己去完成,即需要自己编写ethernetif.c 文件

4、lwIP中每一个网卡都由一个netif结构体来表示

这些结构体描述了各个网卡的底层实现函数及状态,并以链表形式链接起来

补充:

一个nitif结构体,代表一个网卡(网卡抽象为netif)

一个系统中可能有多个网络接口,有可能是以太网,有可能是WIFI,也有可能是其他的网络接口

结构体存在有三种大类功能

结构图

netif结构体

struct netif {

struct netif *next;//指向下一个netif 结构体结构体的指针

ip_addr_t ip_addr; //网络接口的IP地址
ip_addr_t netmask; //网络接口的子网掩码
ip_addr_t gw; //网关

netif_input_fn input;// 向IP层输入数据包的函数  一般指向ethernet_inputh  /ip4_input 函数

netif_output_fn output;//发送IP包的函数  指向数据包待发送函数

netif_linkoutput_fn linkoutput;//该函数实现底层数据包发送

void *state;//指向网卡的信息状态
void* client_data[LWIP_NETIF_CLIENT_DATA_INDEX_MAX +
LWIP_NUM_NETIF_CLIENT_DATA];//client_data字段的主要作用是允许用户在netif结构体中存储额外的信息,用户可以将client_data字段用于存储与网络接口相关的状态信息、配置参数、回调函数等

u16_t mtu;//该接口允许的最大数据包长度 / 最大传输单元

u8_t hwaddr_len;//该接口物理地址长度

u8_t hwaddr[NETIF_MAX_HWADDR_LEN];//该接口的物理地址

u8_t flags;//该接口的状态、属性字段

char name[2];//该接口的名字

u8_t num;//该接口的编号

u8_t rs_count;//需要发送的路由器请求消息的数量
};

netif_add函数添加网卡

全局变量struct netif *netif_default指向的netif结构所表示的网卡为缺省网卡。在发送消息的时候,会首先会通过这个网卡,若是没有回应,再使用其他网卡。

struct netif *
netif_add(struct netif *netif,

          const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,

          void *state, netif_init_fn init, netif_input_fn input)
{


  LWIP_ASSERT_CORE_LOCKED();//执行空



  LWIP_ERROR("netif_add: invalid netif", netif != NULL, return NULL);//网卡合法检查
  LWIP_ERROR("netif_add: No init function given", init != NULL, return NULL);//状态合法检查

#if LWIP_IPV4
  if (ipaddr == NULL) {//IP地址 空 使用默认
    ipaddr = ip_2_ip4(IP4_ADDR_ANY);
  }
  if (netmask == NULL) {//掩码  空 使用默认
    netmask = ip_2_ip4(IP4_ADDR_ANY);
  }
  if (gw == NULL) {//网关   空 使用默认
    gw = ip_2_ip4(IP4_ADDR_ANY);
  }

  /* reset new interface configuration state *///清零
  ip_addr_set_zero_ip4(&netif->ip_addr);
  ip_addr_set_zero_ip4(&netif->netmask);
  ip_addr_set_zero_ip4(&netif->gw);
  netif->output = netif_null_output_ip4;//由用户定义
#endif /* LWIP_IPV4 */    // ip地址 掩码 网关 的合法性检查 和清零

  NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL);//检查数量
  netif->mtu = 0;//该接口允许的最大数据包长度 清零
  netif->flags = 0;//该接口的状态、属性字段 清零
#ifdef netif_get_client_data
  memset(netif->client_data, 0, sizeof(netif->client_data));//允许用户在netif结构体中存储额外的信息 清零
#endif /* LWIP_NUM_NETIF_CLIENT_DATA */


#if LWIP_NETIF_LINK_CALLBACK
  netif->link_callback = NULL;
#endif /* LWIP_NETIF_LINK_CALLBACK */



  /* remember netif specific state information data */
  netif->state = state;//把传入的状态字段 给到网卡
  netif->num = netif_num;//为当前网卡 分配唯一标识符
  netif->input = input;// 网卡的输入 应用层过来 形参传入

  NETIF_RESET_HINTS(netif);


#if LWIP_IPV4
  netif_set_addr(netif, ipaddr, netmask, gw);//给网卡设置ip 子网掩码 网关
#endif /* LWIP_IPV4 */

  /* call user specified initialization function for netif */
  if (init(netif) != ERR_OK) {//初始化网卡
    return NULL;
  }


#if !LWIP_SINGLE_NETIF
  /* Assign a unique netif number in the range [0..254], so that (num+1) can
     serve as an interface index that fits in a u8_t.
     We assume that the new netif has not yet been added to the list here.
     This algorithm is O(n^2), but that should be OK for lwIP.
     */
  {
    struct netif *netif2;
    int num_netifs;
    do {
      if (netif->num == 255) {
        netif->num = 0;
      }
      num_netifs = 0;//netif2 != NULL 因为网卡添加是首部添加 ,而最后初始那个网卡指向的下一个网卡为空;
      for (netif2 = netif_list; netif2 != NULL; netif2 = netif2->next) {//遍历网卡 netif_list此时是表头
        LWIP_ASSERT("netif already added", netif2 != netif);
        num_netifs++;
        LWIP_ASSERT("too many netifs, max. supported number is 255", num_netifs <= 255);
        if (netif2->num == netif->num) {//首部编号为0 新添加的网卡编号也是0  新网卡编号直到不相同,才不用++
          netif->num++;// 
          break;//编号一次次遍历,一次遍历进行累加1次,直到最后一个网卡退出,最后一个网卡不会加了。后面进行+1
        }
      }
    } while (netif2 != NULL);
  }
  if (netif->num == 254) {
    netif_num = 0;
  } else {
    netif_num = (u8_t)(netif->num + 1);//这里就是最后一个网卡不会加了。后面进行+1
  }

  /* add this netif to the list */
  netif->next = netif_list;//新网卡的下一个网卡 指向刚才的网卡表头地址netif_list
  netif_list = netif;//表头地址 指向新卡
#endif /* "LWIP_SINGLE_NETIF */
  mib2_netif_added(netif);



  LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP",
                            netif->name[0], netif->name[1]));
#if LWIP_IPV4 //调试的宏
  LWIP_DEBUGF(NETIF_DEBUG, (" addr "));
  ip4_addr_debug_print(NETIF_DEBUG, ipaddr);
  LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));
  ip4_addr_debug_print(NETIF_DEBUG, netmask);
  LWIP_DEBUGF(NETIF_DEBUG, (" gw "));
  ip4_addr_debug_print(NETIF_DEBUG, gw);
#endif /* LWIP_IPV4 */
  LWIP_DEBUGF(NETIF_DEBUG, ("\n"));

  netif_invoke_ext_callback(netif, LWIP_NSC_NETIF_ADDED, NULL);//空

  return netif;
}

 添加网卡的视图

首部添加

添加之后

第二次学习补充效果图

netif_set_default设置默认网卡

void
netif_set_default(struct netif *netif)
{
  LWIP_ASSERT_CORE_LOCKED();

  if (netif == NULL) {
    /* remove default route */
    mib2_remove_route_ip4(1, netif);//空
  } else {
    /* install default route */
    mib2_add_route_ip4(1, netif);//空
  }
  netif_default = netif;//直接默认的指针,指向该网卡
  LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n",
                            netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\''));
}

默认网卡,为第一个;

netif_remove 网卡移除函数

void
netif_remove(struct netif *netif)
{


  LWIP_ASSERT_CORE_LOCKED();//空

  if (netif == NULL) {//网卡合法检查
    return;
  }

  netif_invoke_ext_callback(netif, LWIP_NSC_NETIF_REMOVED, NULL);//空

#if LWIP_IPV4
  if (!ip4_addr_isany_val(*netif_ip4_addr(netif))) {
    netif_do_ip_addr_changed(netif_ip_addr4(netif), NULL);
  }


#endif /* LWIP_IPV4*/


  if (netif_is_up(netif)) {
    /* set netif down before removing (call callback function) */
    netif_set_down(netif);//移除之前关闭网卡
  }

  mib2_remove_ip4(netif);//移除ip地址

  /* this netif is default? */
  if (netif_default == netif) {//如果是默认网卡,直接让指向默认网卡的指针为空
    /* reset default netif */
    netif_set_default(NULL);
  }
#if !LWIP_SINGLE_NETIF
  /*  is it the first netif? */
  if (netif_list == netif) {//如果是表头 直接让表头指向下一个网卡
    netif_list = netif->next;
  } else {
    /*  look for netif further down the list */
    struct netif *tmp_netif;
    //NETIF_FOREACH(tmp_netif) // 这句为如下的for
     for ((tmp_netif) = netif_list; (tmp_netif) != NULL; (tmp_netif) = (tmp_netif)->next)//从表头,遍历每个网卡
		{
      if (tmp_netif->next == netif) {//找到了当前需要去除的网卡的上一个网卡
        tmp_netif->next = netif->next;//把上一个网卡 指向的下一个网卡的指针  指向下下个网卡
        break;
      }
    }
    if (tmp_netif == NULL) {//如果当前网卡是 最后一个网卡,直接返回;for里面,已经把上一个网卡 指向空
      return; /* netif is not on the list */
    }
  }
#endif /* !LWIP_SINGLE_NETIF */
  mib2_netif_removed(netif);

  LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") );
}

移除网卡效果图

2

lwip(轻量级IP协议栈)是一个开的TCP/IP协议栈,旨在用于嵌入式系统和实时应用。移植lwip 2.1.3到特定的嵌入式系统需要以下步骤: 1. 下载和解压缩lwip软件包:首先,从lwip官方网站上下载最新版本的lwip 2.1.3软件包。然后,将软件包解压缩到本地目录。 2. 配置lwip:进入lwip软件包所在的目录,找到lwipopts.h头文件。通过修改该头文件中的宏定义,根据嵌入式系统的需求配置lwip。可能需要设置的选项包括:IP地址、子网掩码、网关地址、最大数据包长度等。 3. 移植硬件驱动:lwip需要硬件驱动程序来与底层网络接口进行通信。嵌入式系统通常有自己的网络接口硬件,所以需要移植特定的硬件驱动程序。根据硬件接口和规范,实现网络驱动程序和相关函数。 4. 移植操作系统适配层(optional):如果嵌入式系统使用操作系统,如RTOS(实时操作系统),则需要移植操作系统适配层以支持lwip的多线程和并发操作。根据具体的操作系统规范,实现适配层函数和功能。 5. 编译和链接:使用适当的交叉编译工具链,将lwip代码以及硬件驱动程序和适配层代码编译成目标平台的可执行文件。然后,将生成的目标文件链接到嵌入式系统的应用程序中。 6. 调试和测试:在嵌入式系统上运行编译和链接后的 lwip软件,并进行相应的调试和测试。确保lwip在特定的嵌入式环境下能够正常工作,并实现所期望的网络功能。 总之,移植lwip 2.1.3到嵌入式系统需要进行配置、移植硬件驱动程序、可能的操作系统适配层移植、编译和链接等步骤。通过这些步骤,lwip可以在嵌入式系统上实现TCP/IP网络功能,并提供轻量级的网络通信能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值