LwIP之网络接口管理
生活随笔
收集整理的这篇文章主要介绍了
LwIP之网络接口管理
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
协议栈内部使用netif的结构体来描述网络接口,先来看一下这个结构体。
/* netif结构体 */ struct netif {struct netif *next; //用于将netif连接成链表/* IP地址、子网掩码、网关地址 */struct ip_addr ip_addr;struct ip_addr netmask;struct ip_addr gw;/* 向IP层输入数据包 */err_t (* input)(struct pbuf *p, struct netif *inp);/* 发送IP层数据包(先通过ARP查找目的MAC,再调用linkoutput) */err_t (* output)(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr);/* 底层数据包发送 */err_t (* linkoutput)(struct netif *netif, struct pbuf *p);/* 用户字段 */void *state;/* 最大允许数据包长度 */u16_t mtu;/* 物理MAC地址 */u8_t hwaddr_len;u8_t hwaddr[NETIF_MAX_HWADDR_LEN];u8_t flags; //标志位char name[2]; //网络接口名字u8_t num; //网路接口编号 };关于标志位的定义如下
/* 网络接口标志位 */ #define NETIF_FLAG_UP 0x01U /* 网络接口是否已被上层使能 */ #define NETIF_FLAG_BROADCAST 0x02U /* 网络接口是否支持广播 */ #define NETIF_FLAG_POINTTOPOINT 0x04U /* 网络接口是否支持点到点连接 */ #define NETIF_FLAG_DHCP 0x08U /* 网络接口是否支持DHCP功能 */ #define NETIF_FLAG_LINK_UP 0x10U /* 网络接口链路层是否已经使能 */ #define NETIF_FLAG_ETHARP 0x20U /* 网络接口是否支持ARP功能 */ #define NETIF_FLAG_IGMP 0x40U /* 网络接口是否支持IGMP功能 */
LwIP最终会将所有网络接口组织成一个链表
/* 网络接口链表 */ struct netif *netif_list;
netif_add函数用于向协议栈添加一个网络接口
/* 添加一个网络接口到链表 */ struct netif *netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw, void *state, err_t (* init)(struct netif *netif), err_t (* input)(struct pbuf *p, struct netif *netif)) {static u8_t netifnum = 0;/* 清空网路接口成员 */netif->ip_addr.addr = 0;netif->netmask.addr = 0;netif->gw.addr = 0;netif->flags = 0;/* 设置用户数据 */netif->state = state;/* 设置网络接口编号 */netif->num = netifnum++;/* 设置接收回调函数 */netif->input = input;/* 设置IP地址、子网掩码、网关地址 */netif_set_addr(netif, ipaddr, netmask, gw);/* 调用参数提供的init函数,初始化网卡 */if (init(netif) != ERR_OK) {return NULL;}/* 将网络接口添加到链表 */netif->next = netif_list;netif_list = netif;return netif; }netif_remove从协议栈中移除网络接口
/* 从链表中移除一个网络接口 */ void netif_remove(struct netif * netif) {if ( netif == NULL ) return;/* 网络接口在链表头部 */if (netif_list == netif) {/* 删除头节点 */netif_list = netif->next;}else {struct netif * tmpNetif;/* 遍历整个链表 */for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) {/* 删除该节点 */if (tmpNetif->next == netif) {tmpNetif->next = netif->next;break;}}/* 没找到该节点 */if (tmpNetif == NULL)return;}/* 该网络接口为默认网络接口,默认网络接口置为MULL */if (netif_default == netif)netif_set_default(NULL); }
启用和禁止网络接口
/* 使能网络接口 */ void netif_set_up(struct netif *netif) {/* 设置网络接口使能标志位 */if (!(netif->flags & NETIF_FLAG_UP )) {netif->flags |= NETIF_FLAG_UP;/* 广播无回报ARP */if (netif->flags & NETIF_FLAG_ETHARP) {etharp_gratuitous(netif);}} } /* 关闭网络接口 */ void netif_set_down(struct netif *netif) {/* 清空网络接口使能标志位 */if (netif->flags & NETIF_FLAG_UP ){netif->flags &= ~NETIF_FLAG_UP;} } /* 网络接口是否使能 */ u8_t netif_is_up(struct netif *netif) {return (netif->flags & NETIF_FLAG_UP) ? 1 : 0; }
改变IP地址、子网掩码、网关地址函数
/* 网络接口改变IP地址 */ void netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr) {struct tcp_pcb *pcb;struct tcp_pcb_listen *lpcb;/* IP发生变化 */if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0){/* 遍历active状态TCP控制块链表 */pcb = tcp_active_pcbs;while (pcb != NULL) {/* 查找和网络接口IP相同的TCP控制块 */if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {struct tcp_pcb *next = pcb->next;/* TCP连接复位(RST) */tcp_abort(pcb);pcb = next;} else {pcb = pcb->next;}}/* 遍历listen状态TCP控制块链表 */for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {/* 查找和网络接口IP相同的TCP控制块 */if ((!(ip_addr_isany(&(lpcb->local_ip)))) && (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr)))) {/* TCP控制块设置新的本地IP地址 */ip_addr_set(&(lpcb->local_ip), ipaddr);}}}/* 网络接口设置新的IP地址 */ip_addr_set(&(netif->ip_addr), ipaddr); }/* 设置IP地址 */ #define ip_addr_set(dest, src) (dest)->addr = \((src) == NULL? 0:\(src)->addr) /* 网络接口改变子网掩码 */ void netif_set_netmask(struct netif *netif, struct ip_addr *netmask) {/* 网络接口设置新的子网掩码 */ip_addr_set(&(netif->netmask), netmask); } /* 网络接口改变网关地址 */ void netif_set_gw(struct netif *netif, struct ip_addr *gw) {/* 网络接口设置新的网关地址 */ip_addr_set(&(netif->gw), gw); }
通过名字查找网络接口
/* 通过名字查找网络接口,name[0-1]为网络接口名字,name[2]为网络接口编号 */ struct netif *netif_find(char *name) {struct netif *netif;u8_t num;if (name == NULL) {return NULL;}num = name[2] - '0';/* 遍历网络接口链表 */for(netif = netif_list; netif != NULL; netif = netif->next) {/* 匹配网络接口名字 */if (num == netif->num && name[0] == netif->name[0] && name[1] == netif->name[1]) {return netif;}}return NULL; }
LwIP提供了一个默认网络接口
/* 默认网络接口 */ struct netif *netif_default;/* 设置netif为默认网络接口 */ void netif_set_default(struct netif *netif) { netif_default = netif; }
总结
以上是生活随笔为你收集整理的LwIP之网络接口管理的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: Cortex-M3 NVIC与中断控制
- 下一篇: Simulink之三相桥式全控整流电路