Lwip协议netif结构体详解

一、概述

struct netif结构体是lwip协议中非常重要的一个数据结构,每一个网卡都对应一个唯一的netif结构体,当软件中启动dhcp成功获取到ip地址之后,网卡的ip地址、子网掩码、网关地址等信息就会存储到这个netif结构体中,我们可以通过访问这个结构体来获取我们需要得到的信息。

lwip允许设允许存在多个网卡,所以netif通常会存储在一个链表中,以支持多个网卡的设备。

lwip不仅支持ipv4,而且支持ipv6,这里我们仅讨论ipv4.

netif结构体的原型如下(基于lwip2.1.2):

struct netif {
#if !LWIP_SINGLE_NETIF
  /** pointer to next in linked list */
  struct netif *next;
#endif

#if LWIP_IPV4
  /** IP address configuration in network byte order */
  ip_addr_t ip_addr;//ip地址
  ip_addr_t netmask;//子网掩码
  ip_addr_t gw;//网关地址
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
  /** IPV6的地址 */
  ip_addr_t ip6_addr[LWIP_IPV6_NUM_ADDRESSES];
  /** IPV6地址的状态*/
  u8_t ip6_addr_state[LWIP_IPV6_NUM_ADDRESSES];
#if LWIP_IPV6_ADDRESS_LIFETIMES
  /** IPV6的生命周期,如果是特殊值 IP6_ADDR_LIFE_STATIC (0)
   表示IPV6没有生命周期 */
  u32_t ip6_addr_valid_life[LWIP_IPV6_NUM_ADDRESSES];
  u32_t ip6_addr_pref_life[LWIP_IPV6_NUM_ADDRESSES];
#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */
#endif /* LWIP_IPV6 */
  /** 这个函数由网络设备驱动调用,用于将数据包传递给TCP/IP协议栈 */
  netif_input_fn input;
#if LWIP_IPV4
  /** 这个函数由IP层调用,用于发送数据给接口. 它首先解析硬件地址,然后发送数据包.
   *  For ethernet physical layer, this is usually etharp_output() */
  netif_output_fn output;
#endif /* LWIP_IPV4 */
  /** This function is called by ethernet_output() 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_IPV6
  /** This function is called by the IPv6 module when it wants
   *  to send a packet on the interface. This function typically
   *  first resolves the hardware address, then sends the packet.
   *  For ethernet physical layer, this is usually ethip6_output() */
  netif_output_ip6_fn output_ip6;
#endif /* LWIP_IPV6 */
#if LWIP_NETIF_STATUS_CALLBACK
  /** IPV6当设备获取到ip或者失去ip时会调用这个回调函数
   */
  netif_status_callback_fn status_callback;
#endif /* LWIP_NETIF_STATUS_CALLBACK */
#if LWIP_NETIF_LINK_CALLBACK
  /** IPV4当设备获取到ip或者失去ip时会调用这个回调函数
   */
  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;
#ifdef netif_get_client_data
  void* client_data[LWIP_NETIF_CLIENT_DATA_INDEX_MAX + LWIP_NUM_NETIF_CLIENT_DATA];
#endif
#if LWIP_NETIF_HOSTNAME
  /* 网卡的主机名称*/
  const char*  hostname;
#endif /* LWIP_NETIF_HOSTNAME */
#if LWIP_CHECKSUM_CTRL_PER_NETIF
  u16_t chksum_flags;
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/
  /** 最大传输单元 (in bytes) */
  u16_t mtu;
#if LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES
  /** maximum transfer unit (in bytes), updated by RA */
  u16_t mtu6;
#endif /* LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES */
  /** 设备的mac地址 */
  u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
  /** number of bytes used in hwaddr */
  u8_t hwaddr_len;
  /** flags (@see @ref netif_flags) */
  u8_t flags;
  /** descriptive abbreviation */
  char name[2];
  /** number of this interface. Used for @ref if_api and @ref netifapi_netif, 
   * as well as for IPv6 zones */
  u8_t num;
#if LWIP_IPV6_AUTOCONFIG
  /** is this netif enabled for IPv6 autoconfiguration */
  u8_t ip6_autoconfig_enabled;
#endif /* LWIP_IPV6_AUTOCONFIG */
#if LWIP_IPV6_SEND_ROUTER_SOLICIT
  /** Number of Router Solicitation messages that remain to be sent. */
  u8_t rs_count;
#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */
#if MIB2_STATS
  /** link type (from "snmp_ifType" enum from snmp_mib2.h) */
  u8_t link_type;
  /** (estimate) link speed */
  u32_t link_speed;
  /** timestamp at last change made (up/down) */
  u32_t ts;
  /** counters */
  struct stats_mib2_netif_ctrs mib2_counters;
#endif /* MIB2_STATS */
#if LWIP_IPV4 && LWIP_IGMP
  /** This function could be called to add or delete an entry in the multicast
      filter table of the ethernet MAC.*/
  netif_igmp_mac_filter_fn igmp_mac_filter;
#endif /* LWIP_IPV4 && LWIP_IGMP */
#if LWIP_IPV6 && LWIP_IPV6_MLD
  /** This function could be called to add or delete an entry in the IPv6 multicast
      filter table of the ethernet MAC. */
  netif_mld_mac_filter_fn mld_mac_filter;
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
#if LWIP_NETIF_USE_HINTS
  struct netif_hint *hints;
#endif /* LWIP_NETIF_USE_HINTS */
#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结构体中我们可以得到的一些关键信息

2.1、ip地址、网关、子网掩码

#if LWIP_IPV4
  /** IP address configuration in network byte order */
  ip_addr_t ip_addr;//ip地址
  ip_addr_t netmask;//子网掩码
  ip_addr_t gw;//网关地址
#endif /* LWIP_IPV4 */

2.2、IP地址变更通知

netif_status_callback_fn link_callback;

当设备成功获取到ip,或者因为某些原因失去原有的ip(如路由器断电、被路由器踢掉)时,系统会调用这个函数通知应用层进行相应的处理。我们可以自己定义这个回调函数来获取ip改变的信息。

2.3、最大传输单元mtu

MTU指的是在数据传输过程中允许报文的最大长度,在以太网中,这个值最大一般是1500。当传输的报文长度大于MTU时,会分片发送。

2.4、设备的物理地址(MAC)

u8_t hwaddr[NETIF_MAX_HWADDR_LEN];

设备的mac地址

2.5、设备在路由器中显示的名称

  /* 网卡的名称*/
const char*  hostname;

这个名称会显示在路由器中,当我们的手机连接上路由器时,会显示我们的手机名称,如“华为mate30”,这个字段就是在路由器中显示的设备名称。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值