文章目录
1、网络接口简介
- 概念:LwIP支持多种不同的网络接口(网卡),由于网卡是直接与硬件平台联系,硬件不同,处理方式也不相同,所以由用户提供最底层的接口函数,LwIP提供统一的接口,但是底层的实现需要用户自己去完成(ethernetif.c)
一个系统中可能有多个网络接口,有时候是以太网,有时候是WIFI,也有可能是其他网络接口,在LwIP中每个网卡都由一个netif结构体表示,这些结构体描述了网卡的底层实现函数及状态。有多少个网卡,就有多少个netif结构体,这些结构体以链表的形式进行链接。
-
netif结构体功能:用于抽象每个网卡(WIFI/y以太网/…),在结构体中,声明了发送函数、接收函数等等。
-
网络结构的使用过程:当上层需要发送数据,首先需要选择使用哪个网络接口进行转发,如以太网接口,则需要调用以太网netif结构体成员变量所指向的函数进行发送
LwIP网络接口示意图:
- netif屏蔽了硬件接口的差异,完成了对不同网络接口的抽象
2、netif结构体
netif是一个单向的链表
- input:指向数据包输入函数,一般指向ethernet_input函数,也可以是ip4_input函数
- output:检测目标IP是否存在对应的MAC地址,如果没有,先把数据暂存起来,并发送一个ARP请求包,对方主机相应的发送一个ARP应答包
- linkoutput:以太网输出函数是指向low_level_output函数
- link_callback:检测是否存在网线连接
- state:描述网卡状态
- mtu:以太网最大传输单元1500字节
以上成员变量根据相关网卡的特性,针对性填写
3、LWIP的netif相关函数
- netif_init()函数,一般是在lwip_init()函数(内核的初始化)调用
3.1 LwIP网络接口的全局变量
- struct netif *netif_list:指向该链表的表头
- struct netif *netif_default:指向的netif结构所表示的网卡为缺省网卡,在发送消息的时候,会首先通过这个网卡,如果没有回应,再使用其他网卡
3.2 netif_add()函数
函数在netif.c文件中实现
如果需要添加网卡接口,则会定义一个netif:struct netif *netif2;
根据代码,我们最多添加255个网卡
/* add this netif to the list */
netif->next = netif_list;
netif_list = netif;
3.3 netif_remove()
以下是一些主要的步骤,中间可能省略了一些其他步骤
第一步:判断我们要移除的网卡是否为空,不为空跳出相应的if语句,继续执行
第二步:判断要移除的网卡是否处于开启状态,如果是,则将该网卡进行关闭
if (netif_is_up(netif)) {
/* set netif down before removing (call callback function) */
netif_set_down(netif);
}
第三步:判断是否是默认的网卡
/* this netif is default? */
if (netif_default == netif) {
/* reset default netif */
netif_set_default(NULL);
}
第四步,经过上述几个判断之后,开始正式移除网卡
/* 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语句
// #define NETIF_FOREACH(netif) for ((netif) = netif_list; (netif) != NULL; (netif) = (netif)->next)
if (tmp_netif->next == netif) {
tmp_netif->next = netif->next;
break;
}
}
if (tmp_netif == NULL) {
return; /* netif is not on the list */
}
}
3.4 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] : '\''));
}
4、总结
- 搞清楚硬件对应的IP地址、子网掩码、网关;
- netif()有关的函数
- 设置网卡相应的状态