LwIP之网络接口管理
生活随笔
收集整理的這篇文章主要介紹了
LwIP之网络接口管理
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
協(xié)議棧內部使用netif的結構體來描述網絡接口,先來看一下這個結構體。
/* netif結構體 */ struct netif {struct netif *next; //用于將netif連接成鏈表/* IP地址、子網掩碼、網關地址 */struct ip_addr ip_addr;struct ip_addr netmask;struct ip_addr gw;/* 向IP層輸入數(shù)據包 */err_t (* input)(struct pbuf *p, struct netif *inp);/* 發(fā)送IP層數(shù)據包(先通過ARP查找目的MAC,再調用linkoutput) */err_t (* output)(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr);/* 底層數(shù)據包發(fā)送 */err_t (* linkoutput)(struct netif *netif, struct pbuf *p);/* 用戶字段 */void *state;/* 最大允許數(shù)據包長度 */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函數(shù)用于向協(xié)議棧添加一個網絡接口
/* 添加一個網絡接口到鏈表 */ 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;/* 設置用戶數(shù)據 */netif->state = state;/* 設置網絡接口編號 */netif->num = netifnum++;/* 設置接收回調函數(shù) */netif->input = input;/* 設置IP地址、子網掩碼、網關地址 */netif_set_addr(netif, ipaddr, netmask, gw);/* 調用參數(shù)提供的init函數(shù),初始化網卡 */if (init(netif) != ERR_OK) {return NULL;}/* 將網絡接口添加到鏈表 */netif->next = netif_list;netif_list = netif;return netif; }netif_remove從協(xié)議棧中移除網絡接口
/* 從鏈表中移除一個網絡接口 */ void netif_remove(struct netif * netif) {if ( netif == NULL ) return;/* 網絡接口在鏈表頭部 */if (netif_list == netif) {/* 刪除頭節(jié)點 */netif_list = netif->next;}else {struct netif * tmpNetif;/* 遍歷整個鏈表 */for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) {/* 刪除該節(jié)點 */if (tmpNetif->next == netif) {tmpNetif->next = netif->next;break;}}/* 沒找到該節(jié)點 */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地址、子網掩碼、網關地址函數(shù)
/* 網絡接口改變IP地址 */ void netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr) {struct tcp_pcb *pcb;struct tcp_pcb_listen *lpcb;/* IP發(fā)生變化 */if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0){/* 遍歷active狀態(tài)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狀態(tài)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之三相桥式全控整流电路