The embedded device running LWIP protocol stack has multiple network interfaces, and the interface types are different, such as Ethernet interface, serial link interface, etc. In order to effectively manage all interfaces, a netif network interface structure is used to describe each network device in the protocol stack. The kernel organizes the netif structure of all network interfaces in a called netif_list. When IP sends data, the IP layer will select the most appropriate network interface on the linked list according to the destination address of the packet, and call the registered packet sending function to send the data; When receiving a packet, the registered input function is called to submit the packet to the IP layer.
The network interface aims to encapsulate the specific network hardware and software, and provide unified interface services for the protocol stack IP layer.
data structure
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 */ };
The above source code is not complete. Some protocol data structures are omitted, such as SNMP, IGMP, etc.
Next is the pointer to the next netif structure. A given device may have multiple network interfaces and (routers). LWIP will form a linked list of netif structures of all network interfaces for management;
ip_ The addr, netmask and gw fields are used to describe the network address attributes of the network interface, which are IP address, subnet mask and gateway address respectively;
iput is a function pointer. The function function is to submit the data packet received by the network device to the IP layer. The input parameters of the function are pbuf (data packet to be submitted) and netif (network device);
output is a function pointer, which is closely related to the specific network interface device driver. Its function is to send data packets from the IP layer to the destination address;
The functions of linkoutput and output are similar, but they are more basic. They are invoked by ARP module in Ethernet card to complete the transmission of Ethernet data frames.
state is used to record equipment information;
hwaddr_len and hwaddr [] represent the physical address length and specific MAC address information of the network card;
mtu represents the maximum packet length that can be transmitted by the network interface, which is generally set to 1500;
Name [] is used to save the name of each network interface. When some statistical information is output, it is used to represent the corresponding network interface;
Function implementation
The main network interface management function netif_add to see how to register a network interface device in the system.
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_ The add function registers the network interface and adds the network interface to the interface linked list.