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