lwIP Wiki

In lwIP device drivers for physical network hardware are represented by a network interface structure similar to that in BSD. The network interfaces are kept on a global linked list, which is linked by the next pointer in the structure.

Starting a network interface[]

Step One: Add the interface[]

To create a new network interface, the user allocates space for a new struct netif (but does not initialize any part of it) and calls netif_add:

struct *netif netif_add(struct netif *mynetif, struct ip_addr *ipaddr, struct ip_addr *netmask, 
                        struct ip_addr *gw, void *state, err_t (* init)(struct netif *netif), 
                        err_t (* input)(struct pbuf *p, struct netif *netif));

The user specifies an IP address for the interface, its net mask, and gateway address (see IP stack for more details). These can be changed later.

state is a driver-specific structure that defines any other "state" information necessary for the driver to function. Some drivers may require the state variable to be set prior to calling netif_add, but many require this argument to be NULL. Check your driver for more information.

The init parameter specifies a driver-initialization function that should be called once the netif structure has been prepared by netif_add. This parameter may be NULL if the driver has already been initialized in your code elsewhere.

The final parameter input is the function that a driver will call when it has received a new packet. This parameter typically takes one of the following values:

  • ethernet_input: If you are not using a threaded environment and the driver should use ARP (such as for an Ethernet device), the driver will call this function which permits ARP packets to be handled, as well as IP packets.
  • ip_input: If you are not using a threaded environment and the interface is not an Ethernet device, the driver will directly call the IP stack.
  • tcpip_ethinput: If you are using the tcpip application thread (see lwIP and threads), the driver uses ARP, and has defined the ETHARP_TCPIP_ETHINPUT lwIP option. This function is used for drivers that passes all IP and ARP packets to the input function.
  • tcpip_input: If you are using the tcpip application thread and have defined ETHARP_TCPIP_INPUT option. This function is used for drivers that pass only IP packets to the input function. (The driver probably separates out ARP packets and passes these directly to the ARP module). (Someone please recheck this: in lwip 1.4.1 there is no tcpip_ethinput() ; tcp_input() handles ARP packets as well).

Step Two: Bring the interface up[]

An interface that is "up" is available to your application for input and output, and "down" is the opposite state. Therefore, before you can use the interface, you must bring it up. This can be accomplished depending on how the interface gets its IP address. The up/down functions for each type are:

  • Static IP address: use netif_set_up and netif_set_down. Be sure to have set the IP address (during the netif_add or via a netif_set_addr call) before you bring the interface up.
  • DHCP: use dhcp_start and dhcp_stop. This will bring the interface up and set its IP address when it can acquire one.
  • AUTOIP: use autoip_start and autoip_stop. This will bring the interface up and set its IP address when it has chosen one.

To test whether a netif is up, you can use netif_is_up.

Further netif management[]

If you add a netif that should be considered the "default" interface, then you should next call netif_set_default for that netif. When the IP stack tries to route the packet, if it cannot determine the right interface to use, it will send it to the default interface.

If you are using a static IP address, then you can set a network interface's IP address and associated settings with the functions netif_set_ipaddr, netif_set_gw, and netif_set_netmask. You can set all three in one function call using netif_set_addr.

A status callback function is provided by the stack if you set the LWIP_NETIF_STATUS_CALLBACK option in your lwipopts.h file. The status callback will be called anytime the interface is brought up and down. For example, if you would like to log the IP address chosen by DHCP when it has got one, and know when this address changes, then you can use the status callback hook. To set the status callback for a netif, use:

void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback);