LWIP学习笔记-链路层
作者:互联网
网络接口
运行LWIP协议栈的嵌入式设备有多个网络接口,接口类型是各不相同,如以太网接口、串行链路接口等。为实现对所有接口进行有效管理,协议栈内部用一个netif的网络接口结构描述各个网络设。内核将所有网络接口的netif结构组织在一个叫做netif_list的链表上。当IP发送数据时,IP层会根据数据包的目的地址,在链表上选一个最合适的网络接口,并调用注册的数据包发送函数将数据发送出去;当接收数据包时,注册的输入函数被调用,将数据包递交给IP层。
网络接口旨在堆具体的网络硬件、软件进行统一的封装,并为协议栈IP层提供统一的接口服务。
数据结构
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;
/** 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_ above) */
u8_t flags;
/** descriptive abbreviation */
char name[2];
/** number of this interface */
u8_t num;
#if LWIP_NETIF_HWADDRHINT
u8_t *addr_hint;
#endif /* LWIP_NETIF_HWADDRHINT */
#if ENABLE_LOOPBACK
/* List of packets to be queued for ourselves. */
struct pbuf *loop_first;
struct pbuf *loop_last;
#if LWIP_LOOPBACK_MAX_PBUFS
u16_t loop_cnt_current;
#endif /* LWIP_LOOPBACK_MAX_PBUFS */
#endif /* ENABLE_LOOPBACK */
};
上面的源码不是完整的,把一些协议类数据结构省略了,比如SNMP、IGMP等。
next是指向下一个netif结构的指针,一个给设备可能会有多个网络接口及(路由器),LWIP会把所有网络接口的netif结构组成一个链表进行管理;
ip_addr、netmask、gw三个字段用于描述网络接口的网络地址属性,分别是IP地址、子网掩码和网关地址;
iput是一个函数指针,函数功能是将网络设备接收对的数据包提交给IP层,函数的输入参数分别是pbuf(待提交的数据包)、另一个为netif类型(网络设备);
output是一个函数指针,与具体网络接口设备驱动密切相关,功能是将IP层发送数据包到目的地址;
linkoutput和output功能相似,只是更加底层了,主要在以太网卡中被ARP模块中调用,完成以太网数据帧的发送;
state用于记录设备信息;
hwaddr_len和hwaddr[]表示网卡的物理地址长度和具体MAC地址信息;
mtu表示网络接口可传达的最大数据包长度,一般设为1500;
name[]用于保存每一个网络接口的名字,在一些统计信息输出时,用它表示对应的 网络接口;
函数实现
最主要的网络接口管理函数netif_add,看看如何在系统中中注册一个网络接口设备。
struct netif * netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask,
ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input)
{
static u8_t netifnum = 0;
/* reset new interface configuration state */
ip_addr_set_zero(&netif->ip_addr);
ip_addr_set_zero(&netif->netmask);
ip_addr_set_zero(&netif->gw);
netif->flags = 0;
/* remember netif specific state information data */
netif->state = state;
netif->num = netifnum++;
netif->input = input;
netif_set_addr(netif, ipaddr, netmask, gw);
/* call user specified initialization function for netif */
if (init(netif) != ERR_OK) {
return NULL;
}
/* add this netif to the list */
netif->next = netif_list;
netif_list = netif;
return netif;
}
netif_add函数功能是注册网络接口,同时将网络接口加入到接口链表中。
标签:LWIP,addr,ip,笔记,netif,IP,数据包,链路层,网络接口 来源: https://blog.csdn.net/weixin_40401027/article/details/120127089