LWIP(chapter 2.10)网络接口 netif (network interface abstraction)

file netif.c
netif 理解为网卡的抽象,一个网卡对于一个nedif。网卡这里是一个广义概念,具有IP地址的网络装置或者模块。
struct netif *netif_list; 全局链表指针,表示网卡抽象设备链表。下图所示
在这里插入图片描述
netif 属于LWIP的组件,其数据发送和接受的接口实现位于PHY Driver
在这里插入图片描述

netif 是对网络通信接口的抽象
netif关注的是给LWIP 上层使用的借口,
if = interface

/** 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;
/** 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;
#if LWIP_NETIF_STATUS_CALLBACK
  /** This function is called when the netif state is set to up or down
   */
  netif_status_callback_fn status_callback;
#endif /* LWIP_NETIF_STATUS_CALLBACK */
#if LWIP_NETIF_LINK_CALLBACK
  /** This function is called when the netif link is set to up or down
   */
  netif_status_callback_fn link_callback;
#endif /* LWIP_NETIF_LINK_CALLBACK */
#if LWIP_NETIF_REMOVE_CALLBACK
  /** This function is called when the netif has been removed */
  netif_status_callback_fn remove_callback;
#endif /* LWIP_NETIF_REMOVE_CALLBACK */
  /** This field can be set by the device driver and could point
   *  to state information for the device. */
  void *state;
#if LWIP_DHCP
  /** the DHCP client state information for this netif */
  struct dhcp *dhcp;
#endif /* LWIP_DHCP */
#if LWIP_AUTOIP
  /** the AutoIP client state information for this netif */
  struct autoip *autoip;
#endif
#if LWIP_NETIF_HOSTNAME
  /* the hostname for this netif, NULL is a valid value */
  char*  hostname;
#endif /* LWIP_NETIF_HOSTNAME */
  /** 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_SNMP
  /** link type (from "snmp_ifType" enum from snmp.h) */
  u8_t link_type;
  /** (estimate) link speed */
  u32_t link_speed;
  /** timestamp at last change made (up/down) */
  u32_t ts;
  /** counters */
  u32_t ifinoctets;
  u32_t ifinucastpkts;
  u32_t ifinnucastpkts;
  u32_t ifindiscards;
  u32_t ifoutoctets;
  u32_t ifoutucastpkts;
  u32_t ifoutnucastpkts;
  u32_t ifoutdiscards;
#endif /* LWIP_SNMP */
#if LWIP_IGMP
  /** This function could be called to add or delete a entry in the multicast
      filter table of the ethernet MAC.*/
  netif_igmp_mac_filter_fn igmp_mac_filter;
#endif /* LWIP_IGMP */
#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 */
};

netif中的接口都是函数指针,所以函数指针需要初始化才能由函数实体。所以很容易联想到,网卡的初始化。
netif 中其他变量的作用在了解LWIP整体前,细究其作用并不大。
所以对于网卡来说,需要提供给netif 几个接口

  1. in :网络设备取货的数据,完成对应的解析,装载到pbuf ,提供给IP层
  2. out:上层不数据状图pbuf然后调用函数发送数据
  3. 初始化,netif初始化和网络设备的初始化。

把netif 加入到struct netif *netif_list; 全局链表指针 的过程称为注册。

/**
 * Add a network interface to the list of lwIP netifs.
 *
 * @param netif a pre-allocated netif structure
 * @param ipaddr IP address for the new netif
 * @param netmask network mask for the new netif
 * @param gw default gateway IP address for the new netif
 * @param state opaque data passed to the new netif
 * @param init callback function that initializes the interface
 * @param input callback function that is called to pass
 * ingress packets up in the protocol layer stack.
 *
 * @return netif, or NULL if failed.
 */
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)

ethernetif.c 是一个例子

/* * This file is a skeleton for developing Ethernet network
interface * drivers for lwIP. Add code to the low_level functions and
do a * search-and-replace for the word “ethernetif” to replace it
with * something that better describes your network interface. */

ethernetif_init(struct netif *netif)

/** * Should be called at the beginning of the program to set up the

  • network interface. It calls the function low_level_init() to do the * actual setup of the hardware. * * This function should be passed as a parameter to netif_add(). * * @param netif the lwip network
    interface structure for this ethernetif * @return ERR_OK if the
    loopif is initialized * ERR_MEM if private data couldn’t be
    allocated * any other err_t on error */

网络设备的初始化时通过
/* initialize the hardware */
low_level_init(netif);

low_level_XXX函数时网络设备的接口实现。
在这里插入图片描述
在这里插入图片描述

一个netif 初始化过程

void
netif_init(void)
{
#if LWIP_HAVE_LOOPIF
  ip_addr_t loop_ipaddr, loop_netmask, loop_gw;
  IP4_ADDR(&loop_gw, 127,0,0,1);
  IP4_ADDR(&loop_ipaddr, 127,0,0,1);
  IP4_ADDR(&loop_netmask, 255,0,0,0);

#if NO_SYS
  netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, ip_input);
#else  /* NO_SYS */
  netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, tcpip_input);
#endif /* NO_SYS */
  netif_set_up(&loop_netif);

#endif /* LWIP_HAVE_LOOPIF */
}

netif 输入与输出

/**
 * This function should be called when a packet is ready to be read
 * from the interface. It uses the function low_level_input() that
 * should handle the actual reception of bytes from the network
 * interface. Then the type of the received packet is determined and
 * the appropriate input function is called.
 *
 * @param netif the lwip network interface structure for this ethernetif
 */
static void
ethernetif_input(struct netif *netif)

ethernetif_input调用low_level_input获取网络设备接收到的数据
根据帧类型忘上层递交

ethernetif_input 会递交到ethernet_input
在这里插入图片描述
IRQ 中断发送后代表 ETH网络设备首到一帧数据,LWIP对网络设备数据输入从ethernetif_input开始

ethernetif_input调用ETH网络设备的 Low_level_input获取以太网帧到pbuf

ethernetif_input把收到的数据往上递交到erthnet_input。erthnet_input 在netif_add作为参数传入到netif。

所以接收以太网帧的过程是一个数据递交过程。erthnet_input 位于ARP

对长度和类型判断数据包是ARP包还是IP包。IP包需要递交到IP。ARP递交到ARP。
在这里插入图片描述
以太网帧的数据是向上递交的过程。

在这里插入图片描述
etharp_ip_input,

1.etharp_ip_input会判断这个IP数据报中的目的IP是不是本地网络,如果不是那么丢弃。
2.收到的IP报可以用于更新ARP列表。
ip_input 分支做简单的处理后发往上层(例如TCP)
在这里插入图片描述
etharp_arp_input分支。完成对ARP的应答和处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值