LwIP 之二 网络接口 netif(netif.c、ethernetif( 二 )


netif 链表
LwIP 使用链表(单向链表)来管理多个网络接口 。在 netif.c 中有如下全局变量netif *; 和netif *; , 其中前者就是网络接口链表指针 , 后者表示默认情况下(有多网口时)使用哪个网络接口 。
netif.c中第一部分就是添加一个会换接口(即 127.0.0.1) 。具体函数为 void (void) 。该函数在 LwIP 初始化时被调用( ->-> ) 。
要使用 LwIP 必须调用完成对 LwIP 的初始化 。
主要接口
向网络接口链表中添加新接口必须通过以下函数
struct netif *netif_add(struct netif *netif,#if LWIP_IPV4const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,#endif /* LWIP_IPV4 */void *state, netif_init_fn init, netif_input_fn input);
下面简单具体分析以下添加新接口:

LwIP 之二 网络接口 netif(netif.c、ethernetif

文章插图
网络接口链表的操作非常简单 , 新添加的接口在链表最前面!
从网络接口链表中删除指定的接口必须通过 void ( netif *netif); 这个接口来实现 。删除也非常简单 , 遍历链表找到指定的接口 , 从链表中移除 , 然后释放相关资源!
netif 使用
那么具体该如何使用呢?其实使用还是非常简单的 。首先我们需要针对我们的网络接口定义一个 netif 结构体变量netif ; , 接下来就是初始化 。通过上面的结构不难发现 , 其中有非常多的函数指针 , 后续对于网络接口的操作 , 基本全是通过各个函数指针来实现的!通常 , 我们会在 LwIP 初始化中 , 用以下函数添加自己的网络接口:
struct netif xnetif; /* 通过该函数 , 将网络接口添加到链表中 */netif_add(&xnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_input);/*Registers the default network interface.*/netif_set_default(&xnetif);if (EthStatus == (ETH_INIT_FLAG | ETH_LINK_FLAG)){/* Set Ethernet link flag */xnetif.flags |= NETIF_FLAG_LINK_UP;/* When the netif is fully configured this function must be called.*/netif_set_up(&xnetif);}else{/*When the netif link is down this function must be called.*/netif_set_down(&xnetif);}
当我们有多个网口时 , 则需要多次调用以上接口来添加多个网口(示例如下) 。我这里为每个网口都定义了独立接口 , 也可以用同一个接口 , 然后根据入参判断是哪个网口然后分别处理 。
LwIP 的网络驱动有一定的模型 , /src/netif/.c 文件即为底层接口的驱动的模版 , 用户为自己的网络设备实现驱动时应参照此模块 。该文件中的函数通常为与硬件打交道的函数 , 当有数据接收的时候被调用 , 以使接收到的数据进入 tcpip 协议栈 。
从 2.1.x 版本及之后 , 该模板文件可以从官网的 -2.1.0 中找到 这个名字仅仅是一个示例 , LwIP 建议将其更改为一个符合自己的名字
这里需要注意 ,  中的对外接口都是通过相应的 API 注册到 LwIP 内部 , 因此 , 这部分接口没有在 LwIP 中直接调用(直接搜索不到) 。还有就是 , 在实际使用中 , 我们通常会比给出的模板额外增加几个接口 。
结构体
【LwIP 之二 网络接口 netif(netif.c、ethernetif】上面说过 , 每个 netif 接口都需要一个底层接口文件提供访问硬件的支持 。在 LwIP 提供的模板 .c 文件中(该模板文件可以从官网的 -2.1.0 中找到) , 上来就是一个如下的结构体: