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

本文详细介绍了TCP/IP协议栈中的网络接口层,包括物理层、逻辑链路控制层(MAC与LLC子层)的职责,以太网数据帧结构,以及网络接口管理。重点讲解了LwIP如何管理不同网络接口,网络接口的描述结构netif,以及环回接口的工作原理和应用场景。
摘要由CSDN通过智能技术生成

一、网络接口层简介

前面提到TCP/IP可分为四层,最底层是网络接口层,实际可细分为物理层和逻辑链路层,逻辑链路层又可细分为介质访问控制子层(即MAC层)与逻辑链路控制子层(即LLC层),大致关系如下:
网络接口层结构

1.1 物理层

物理层通过把上层的比特流(0/1二进制流)转换为电压的高低、灯光的亮灭等物理信号将数据传输出去,接收端收到这些物理信号后再将这些电压的高低、灯光的亮灭信号恢复为比特流。因此,物理层的规范中包括比特流的转换规则和传输介质两部分。

物理层传输介质大体可分为有线传输介质与无线传输介质两大类:有线传输介质有同轴电缆、双绞线、光纤电缆等;无线传输介质有蓝牙、Wi-Fi、红外线IrDA、移动通信等。

物理层比特流的转换规则就是数据编解码方法,根据信号类型也可分为模拟数据编码和数字数据编码两大类:模拟数据编码(常用于无线传输介质)主要分为振幅键控(ASK)、移频键控(FSK)、移相键控(PSK)等;数字数据编码(常用于有线传输介质)主要分为非归零码NRZ、曼切斯特编码、差分曼切斯特编码等。编码图示如下:
模拟数据编码
数字数据编码

1.2 逻辑链路控制层

MAC子层的主要作用也可分为两部分:一部分面向上层LLC负责把物理层的0/1比特流组建成数据帧或把数据帧分解为0/1比特流(数据帧的封装与卸装),包括数据帧的寻址、识别、发送、接收、差错控制等;另一部分面向下层PHY提供对共享介质的访问方法,包括以太网的带冲突检测的载波侦听多路访问(CSMA/CD)、令牌环(TokenRing)、光纤分布式数据接口(FDDI)等。

MAC子层对介质的访问控制主要包括介质分配(避免碰撞)和竞争裁决(碰撞处理),对传输介质的访问可大体分为共享介质和非共享介质两类:共享介质指多个设备共享一个通信介质,包括蓝牙/WIFI使用的无线信道,为了避免多个设备同时发送数据帧引起冲突,常在发送数据帧前检测通信介质上的数据流动情况,一般为半双工通信;非共享介质主要是每个设备直连交换机,由交换机负责转发数据帧,每个设备与交换机之间的通信介质是专用的,这种情况不需要进行冲突检测,可实现全双工通信。

MAC子层管理的数据帧为了便于寻址,包含物理地址字段(也叫MAC地址),数据帧也正是靠源MAC地址与目的MAC地址实现数据帧的寻址(仅限于同一数据链路段,可以跨交换机、网桥、中继器等链路层中转设备,但不能跨路由器等网络层中转设备,跨越路由器的寻址靠IP地址完成)、发送与接收的。MAC子层将目标计算机的物理地址添加到数据帧上,当此数据帧传递到对端的MAC子层后,它检查该地址是否与自己的地址相匹配,如果帧中的地址与自己的地址不匹配,就将这一帧抛弃;如果相匹配,就将它发送到上一层中。在有线介质比如以太网或FDDI中根据IEEE802.3的规范使用MAC地址,在无线介质比如Wi-Fi(IEEE802.11)、蓝牙(IEEE802.15)等设备中也使用相同规范的MAC地址,所以MAC子层的存在屏蔽了不同物理链路种类的差异性。

MAC地址长48比特,在使用网卡(NIC)的情况下,MAC地址一般会被烧入到ROM中。因此,任何一个网卡的MAC地址都是唯一的,在全世界都不会重复(实际上有例外情况,比如虚拟MAC地址可能有重复,重复的MAC地址只要不是同属于一个数据链路就不会出现问题,一个主机是靠IP地址与MAC地址共同唯一确定的)。MAC地址中3~24位表示厂商识别码OUI(Organizationally unique identifier),每个NIC厂商都有特定唯一的识别数字,后24位是厂商内部为识别每个网卡而用的,前两位则跟MAC地址类型有关,MAC地址的结构如下图示:
MAC地址结构
MAC地址的源地址就是真实的MAC地址(属于单播地址),目的地址则可分为三类:单播地址、多播地址和广播地址。单播地址通常与一个网卡的具体地址相对应,它要求第一个字节的bit0(即最先发出去的位)必须为0;多播地址则要求第一个字节的bit0为1,在网络中多播地址不会与任何网卡的MAC地址相同,而多播数据可以被多个网卡同时接收;广播地址的所有48位全为1(即FF-FF-FF-FF-FF-FF),同一链路层局域网中的所有网卡都可以接收到广播数据包。

LLC子层向高层提供一个或多个逻辑接口,这些接口被称为服务访问点(SAP),多个逻辑接口可能共用一个物理接口,每个逻辑接口可能通过SAP服务一个上层协议。LLC子层将物理链路抽象为逻辑链路,基本与物理介质完全无关了,屏蔽了不同MAC子层之间的差异,对上层网络层来的不同协议进行翻译和控制,并向下传递同样的数据帧,以使其可以在物理层传送。相对于有线传输的线缆直连,无线传输的链路管理更为复杂,需要将电磁波资源划分为不同的信道,无线链路的建立、加密、认证、释放等也是由LLC规定的,读者感兴趣可以详细了解下IEEE802.11(Wi-Fi)与IEEE802.15(BlueTooth)的规范,本系列主要介绍更上层的协议栈,就以IEEE802.3以太网规范为例了。下面列出部分数据链路名及其主要参数供参考:
常用数据链路

1.3 以太网数据帧简介

目前有线传输使用较广的是以太网,下面先介绍下以太网的数据帧构成如下:
以太网数据帧构成
现在使用比较多的以太网帧是前者,跟IEEE802.3定义的以太网帧略有差别,两者前面都包含目标MAC地址与源MAC地址字段,用于数据帧的寻址、发送、接收等,最后都有FCS(Frame Check Sequence)用于差错校验。不同的是源MAC地址后与数据前的部分,以太网帧的类型字段用于标识上层协议类型,而IEEE802.3帧的帧长度字段不足以标识上层协议类型,需要靠LLC/SNAP(SubNetwork Access Protocol)字段标识出上层协议类型信息。常见的协议类型编号如下:
以太网主要类型协议编号
以太网帧前端还有一个叫做前导码的部分,它由0/1交替组合而成,表示一个以太网帧的开始,也是为了实现物理层数据的正确传输,物理层使用7个字节的前同步码实现物理层帧输入/输出的同步,使用1个字节的SFD(Start Frame Delimiter帧首定界符,末尾是11)标识帧的开始,共8字节的前导码结构如下:
前导码结构
以太网的数据帧相对比较简单,基本省去了LLC子层的部分,Wi-Fi/蓝牙的链路层数据帧就比较复杂了,专门介绍蓝牙/Wi-Fi时再详细介绍。

链路层数据帧的封装属于网卡驱动的范畴,并不算TCP/IP协议栈的部分,这里就不详细介绍链路层数据帧的数据结构和操作函数的实现了。下面介绍TCP/IP协议栈对不同网卡抽象出的网络接口如何管理,由于从一台主机寻址到另一台主机,需要IP地址进行网际寻址、MAC地址进行局域网内寻址,所以每个网络接口都会有一个IP地址和一个MAC地址,具体寻址过程下一篇介绍。

二、网络接口管理

网络接口层旨在对具体网络硬件、软件进行统一的封装,并为协议栈上层(IP层)提供统一的接口服务。在LwIP运行的目标系统上可能存在多个网络接口,比如可能有多个网卡,也可能有串行网络接口(串口),还可能有环回接口(提供了一种对硬件接口的纯软件模拟,允许用户在没有硬件网络接口的环境下运行并调试协议栈,也可用于进程间通信)。

为了实现对这些接口结构的有效管理,LwIP会为每个接口分配一个netif结构,用这个结构来描述每种接口的特性,如接口IP、接口状态等,同时在该结构中为每个接口注册对应的操作函数,如数据包输入函数、输出函数等。内核将所有网络接口的netif结构组织在一个叫做netif_list的链表上,当有IP数据包需要发送时,IP层会根据数据包的目的IP地址,在netif_list链表中选择一个最合适的网络接口,并调用其注册的数据包发送函数将数据包发送出去;当网卡接收到数据包时,其注册的数据包输入函数会被调用,完成将数据包递交给IP层的任务。从整个过程来看,网络接口管理有效地为上层屏蔽掉底层各个硬件接口间的差异,并为底层网络接口驱动程序的编写提供了规范化的接口定义。

2.1 网络接口的描述

数据结构netif是协议栈内核的重要组成部分,它完成了对各种类型网络接口的抽象。下面先看下该数据结构的实现代码:

// rt-thread\components\net\lwip-1.4.1\src\include\lwip\netif.h

/** Generic data structure used for all lwIP network interfaces.
 *  The following fields should be filled in by the initialization
 *  function for the device driver: hwaddr_len, hwaddr[], mtu, flags */
struct netif {
   
  /** pointer to next in linked list */
  struct netif *next;

  /** IP address configuration in network byte order */
  ip_addr_t ip_addr;
  ip_addr_t netmask;
  ip_addr_t gw;

  /** This function is called by the network device driver
   *  to pass a packet up the TCP/IP stack. */
  netif_input_fn input;
  /** This function is called by the IP module when it wants
   *  to send a packet on the interface. This function typically
   *  first resolves the hardware address, then sends the packet. */
  netif_output_fn output;
  /** This function is called by the ARP module when it wants
   *  to send a packet on the interface. This function outputs
   *  the pbuf as-is on the link medium. */
  netif_linkoutput_fn linkoutput;

  /** This field can be set by the device driver and could point
   *  to state information for the device. */
  void *state;
  /** maximum transfer unit (in bytes) */
  u16_t mtu;
  /** number of bytes used in hwaddr */
  u8_t hwaddr_len;
  /** link level hardware address of this interface */
  u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
  /** flags (see NETIF_FLAG_ below) */
  u8_t flags;
  /** descriptive abbreviation */
  char name[2];
  /** number of this interface */
  u8_t num;

#if ENABLE_LOOPBACK
  /* List of packets to be queued for ourselves. */
  struct pbuf *loop_first;
  struct pbuf *loop_last;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流云IoT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值