协议栈内部使用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之网络接口管理相关推荐

  1. LWIP学习笔记(4)LWIP网络接口管理

    网络接口简介 网卡是一块被设计用来允许计算机在计算机网络上进行通讯的计算机硬件.每一个网卡都有一个被称为MAC地址的独一无二的48位串行号,在osi模型的第一层.网卡的主要工作原理是整理计算机上发往网 ...

  2. Lwip从入门到放弃之(四)---网络接口管理

    对网络接口的有效管理,是协议栈能与外部进行通信的关键.我们把网络接口管理描述成链路层的部分,它旨在对具体网络硬件.软件进行统一的封装,并未IP层提供统一的接口服务. 为了实现对这些接口的管理,LwIP ...

  3. TCP/IP协议栈之LwIP(二)---网络接口管理

    文章目录 一.网络接口层简介 1.1 物理层 1.2 逻辑链路控制层 1.3 以太网数据帧简介 二.网络接口管理 2.1 网络接口的描述 2.2 网络接口的操作 三.特殊的环回接口 更多文章 一.网络 ...

  4. LWIP网络接口管理

    LAN8720+RJ45+MAC(STM32F4自带的)构成了网络接口层. 转载于:https://www.cnblogs.com/gary-guo/p/5705705.html

  5. LWIP学习笔记(3)LWIP数据包管理结构pbuf

    pbuf:LWIP是TCP/IP协议栈的一种具体体现,本质就是对数据包的处理,在LWIP中使用一个被称为pbuf的结构体管理数据包,LWIP源码中的pbuf.c和pbuf.h这两个文件就是关于pbuf ...

  6. LwIP应用笔记(二):无操作系统支持下的RAW API移植

    欢迎来我的个人博客转转:https://www.codinglover.top 写在前面 由于从这篇博客开始要涉及代码编写了,为此笔者自行画板搭建了一个实验平台,以后的所有代码与步骤都会在此实验平台上 ...

  7. 使用标准库对STM32F407ZGT6移植LWIP(逻机-全网最全)

    使用STM32CubeM对F407ZGT6移植LWIP(全网最全) 使用标准库对STM32F407ZGT6移植LWIP(逻机-全网最全) 基于STM32单片机的LwIP协议(一)网络协议简介 基于ST ...

  8. LWIP再探----内存池管理

    这这里是接上一篇内存池管理部分的,这里如果读者一打开memp.c的话会感觉特别那一理解原作者在干嘛,但是看懂了就明白原作者是怎么巧妙的使用了宏.废话不多说先说了下我分析是一下宏的条件是 前提条件 ME ...

  9. 物联网LWIP网络开发 LWIP网卡设计原理11.1 协议栈内存管理

    lwIP协议栈内存管理上 lwIP 内存管理需求 常用内存管理需求 静态分配的变量 -> RAM 任务堆栈 动态存储器管理 malloc & free lwip内存管理需求 lwip 内 ...

最新文章

  1. 常见浏览器User-Agent大全
  2. Linux内核之于红黑树and AVL树
  3. Ubuntu nginx 配置实例
  4. Hive的union和join操作
  5. opencv精要(4)-fedora下的opencv安装及测试,codelite配置
  6. mockito接口没法赋值_Mockito:无法实例化@InjectMocks字段:类型是接口
  7. Python开发中收集的一些常用功能Demo
  8. 快速排序c语言实现,快速排序的C语言代码实现
  9. Golang程序性能分析(一)pprof和go-torch
  10. docker network bridge模式,自定义(一)
  11. python编程狮app题库_‎Python编程狮-零基础学Python App Storessa
  12. Hessian Matrix
  13. python and or 详解
  14. 前端之JavaScript入门篇
  15. 王亮:游戏AI探索之旅——从alphago到moba游戏
  16. 什么是短连接,如何用 Python 生成短连接?
  17. 沃顿商学院自我管理课——完美融合
  18. 计算机科学家安内尔,历届诺贝尔生理学或医学奖获奖者简介
  19. css保持图片原始比例
  20. 本地计算机用户组,管理本地用户与组账户

热门文章

  1. C++\Python\Qt工作笔记-读取txt文件查找某行是否包含keyWord
  2. 计算机板报设计简单,计算机板报制作
  3. php数组10000分割1000_PHP切割整数工具类似微信红包金额分配的思路详解
  4. keil4内嵌汇编_keil C中嵌入汇编程序的方法
  5. 华为鲁勇:云市场进入新阶段,千行百业数字化大市场将是决胜场
  6. HashMap 源码
  7. android从github 下开源库引用问题 (出现ClassNotFoundException)
  8. 操作系统之文件管理:5、文件物理结构(连续分配、链式(显式、隐式)分配、索引分配(链接、多层索引、混合索引))
  9. 字扩展、位扩展、字位同时扩展
  10. Dockerfile语法简介(精)