lwIP 2.2.1 Lightweight IP stack

Functions
Mainloop mode ("NO_SYS")
lwIP

## Functions
void | lwip_init (void)
err_t | ip_input (struct pbuf *p, struct netif *inp)
err_t | netif_input (struct pbuf *p, struct netif *inp)
void | sys_check_timeouts (void)
err_t | ethernet_input (struct pbuf *p, struct netif *netif)

## Detailed Description

Use this mode if you do not run an OS on your system. #define NO_SYS to 1. Feed incoming packets to netif->input(pbuf, netif) function from mainloop, not from interrupt context. You can allocate a Packet buffers (PBUF) in interrupt context and put them into a queue which is processed from mainloop.
Call sys_check_timeouts() periodically in the mainloop.
Porting: implement all functions in Time, Critical sections and Compiler/platform abstraction.
You can only use "raw" APIs in this mode.
Sample code:

void
eth_mac_irq()
{
/* Service MAC IRQ here */
/* Allocate pbuf from pool (avoid using heap in interrupts) */
struct pbuf* p = pbuf_alloc(PBUF_RAW, eth_data_count, PBUF_POOL);
if(p != NULL) {
/* Copy ethernet frame into pbuf */
pbuf_take(p, eth_data, eth_data_count);
/* Put in a queue which is processed in main loop */
if(!queue_try_put(&queue, p)) {
/* queue is full -> packet loss */
pbuf_free(p);
}
}
}
static err_t
netif_output(struct netif *netif, struct pbuf *p)
{
LINK_STATS_INC(link.xmit);
/* Update SNMP stats (only if you use SNMP) */
MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
int unicast = ((p->payload[0] & 0x01) == 0);
if (unicast) {
MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
} else {
MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
}
lock_interrupts();
pbuf_copy_partial(p, mac_send_buffer, p->tot_len, 0);
/* Start MAC transmit here */
unlock_interrupts();
return ERR_OK;
}
static void
netif_status_callback(struct netif *netif)
{
printf("netif status changed %s\n", ip4addr_ntoa(netif_ip4_addr(netif)));
}
static err_t
netif_init(struct netif *netif)
{
netif->linkoutput = netif_output;
netif->output = etharp_output;
netif->output_ip6 = ethip6_output;
netif->mtu = ETHERNET_MTU;
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6;
MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, 100000000);
SMEMCPY(netif->hwaddr, your_mac_address_goes_here, ETH_HWADDR_LEN);
netif->hwaddr_len = ETH_HWADDR_LEN;
return ERR_OK;
}
void
main(void)
{
struct netif netif;
lwip_init();
netif_add(&netif, IP4_ADDR_ANY, IP4_ADDR_ANY, IP4_ADDR_ANY, NULL, netif_init, netif_input);
netif.name[0] = 'e';
netif.name[1] = '0';
netif_create_ip6_linklocal_address(&netif, 1);
netif_set_status_callback(&netif, netif_status_callback);
netif_set_default(&netif);
netif_set_up(&netif);
/* Start DHCP and HTTPD */
dhcp_start(&netif );
httpd_init();
while(1) {
/* Check link state, e.g. via MDIO communication with PHY */
if(link_state_changed()) {
if(link_is_up()) {
netif_set_link_up(&netif);
} else {
netif_set_link_down(&netif);
}
}
/* Check for received frames, feed them to lwIP */
lock_interrupts();
struct pbuf* p = queue_try_get(&queue);
unlock_interrupts();
if(p != NULL) {
LINK_STATS_INC(link.recv);
/* Update SNMP stats (only if you use SNMP) */
MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
int unicast = ((p->payload[0] & 0x01) == 0);
if (unicast) {
MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
} else {
MIB2_STATS_NETIF_INC(netif, ifinnucastpkts);
}
if(netif.input(p, &netif) != ERR_OK) {
pbuf_free(p);
}
}
/* Cyclic lwIP timers check */
sys_check_timeouts();
/* your application goes here */
}
}

## Function Documentation

## ◆ ethernet_input()

err_t ethernet_input | ( | struct pbuf * | p,
|  | struct netif * | netif
| ) |  |

Process received ethernet frames. Using this function instead of directly calling ip_input and passing ARP frames through etharp in ethernetif_input, the ARP cache is protected from concurrent access.
Don't call directly, pass to netif_add() and call netif->input().

Parameters

  p | the received packet, p->payload pointing to the ethernet header
  netif | the network interface on which the packet was received

See also
  LWIP_HOOK_UNKNOWN_ETH_PROTOCOL
  ETHARP_SUPPORT_VLAN
  LWIP_HOOK_VLAN_CHECK

## ◆ ip_input()

err_t ip_input | ( | struct pbuf * | p,
|  | struct netif * | inp
| ) |  |

If both IP versions are enabled, this function can dispatch packets to the correct one. Don't call directly, pass to netif_add() and call netif->input().

## ◆ lwip_init()

void lwip_init | ( | void |  | ) |

Initialize all modules. Use this in NO_SYS mode. Use tcpip_init() otherwise.

## ◆ netif_input()

err_t netif_input | ( | struct pbuf * | p,
|  | struct netif * | inp
| ) |  |

Forwards a received packet for input processing with ethernet_input() or ip_input() depending on netif flags. Don't call directly, pass to netif_add() and call netif->input(). Only works if the netif driver correctly sets NETIF_FLAG_ETHARP and/or NETIF_FLAG_ETHERNET flag!

## ◆ sys_check_timeouts()

void sys_check_timeouts | ( | void |  | ) |

Handle timeouts for NO_SYS==1 (i.e. without using tcpip_thread/sys_timeouts_mbox_fetch(). Uses sys_now() to call timeout handler functions when timeouts expire.

Must be called periodically from your main loop.

PBUF_POOL
@ PBUF_POOL
Definition: pbuf.h:167
NETIF_FLAG_IGMP
#define NETIF_FLAG_IGMP
Definition: netif.h:104
netif_set_up
void netif_set_up(struct netif *netif)
Definition: netif.c:871
PBUF_RAW
@ PBUF_RAW
Definition: pbuf.h:111
dhcp_start
err_t dhcp_start(struct netif *netif)
Definition: dhcp.c:810
netif::input
netif_input_fn input
Definition: netif.h:297
httpd_init
void httpd_init(void)
Definition: httpd.c:2697
ip4addr_ntoa
char * ip4addr_ntoa(const ip4_addr_t *addr)
Definition: ip4_addr.c:269
pbuf::tot_len
u16_t tot_len
Definition: pbuf.h:200
MIB2_INIT_NETIF
#define MIB2_INIT_NETIF(netif, type, speed)
Definition: snmp.h:119
NETIF_FLAG_ETHARP
#define NETIF_FLAG_ETHARP
Definition: netif.h:97
pbuf_take
err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len)
Definition: pbuf.c:1236
pbuf_free
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:729
netif::mtu
u16_t mtu
Definition: netif.h:344
netif::flags
u8_t flags
Definition: netif.h:354
netif_create_ip6_linklocal_address
void netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit)
Definition: netif.c:1551
netif::linkoutput
netif_linkoutput_fn linkoutput
Definition: netif.h:308
pbuf_copy_partial
u16_t pbuf_copy_partial(const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
Definition: pbuf.c:1061
netif::hwaddr
u8_t hwaddr[6U]
Definition: netif.h:350
IP4_ADDR_ANY
#define IP4_ADDR_ANY
Definition: ip_addr.h:417
pbuf_alloc
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:226
etharp_output
err_t etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr)
Definition: etharp.c:792
MIB2_STATS_NETIF_INC
#define MIB2_STATS_NETIF_INC(n, x)
Definition: snmp.h:105
netif
Definition: netif.h:269
netif_input
err_t netif_input(struct pbuf *p, struct netif *inp)
Definition: netif.c:228
netif::hwaddr_len
u8_t hwaddr_len
Definition: netif.h:352
netif::name
char name[2]
Definition: netif.h:356
sys_check_timeouts
void sys_check_timeouts(void)
Definition: timeouts.c:352
netif_set_default
void netif_set_default(struct netif *netif)
Definition: netif.c:849
ERR_OK
@ ERR_OK
Definition: err.h:55
err_t
s8_t err_t
Definition: err.h:96
NETIF_FLAG_ETHERNET
#define NETIF_FLAG_ETHERNET
Definition: netif.h:101
SMEMCPY
#define SMEMCPY(dst, src, len)
Definition: opt.h:145
MIB2_STATS_NETIF_ADD
#define MIB2_STATS_NETIF_ADD(n, x, val)
Definition: snmp.h:110
netif_set_link_down
void netif_set_link_down(struct netif *netif)
Definition: netif.c:1056
ethip6_output
err_t ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr)
Definition: ethip6.c:79
lwip_init
void lwip_init(void)
Definition: init.c:342
netif_set_link_up
void netif_set_link_up(struct netif *netif)
Definition: netif.c:1018
netif_add
struct netif * netif_add(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input)
Definition: netif.c:287
pbuf
Definition: pbuf.h:186
NETIF_FLAG_MLD6
#define NETIF_FLAG_MLD6
Definition: netif.h:107
netif::output_ip6
netif_output_ip6_fn output_ip6
Definition: netif.h:314
netif_set_status_callback
void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback)
Definition: netif.c:987
netif::output
netif_output_fn output
Definition: netif.h:303
pbuf::payload
void * payload
Definition: pbuf.h:191
NETIF_FLAG_BROADCAST
#define NETIF_FLAG_BROADCAST
Definition: netif.h:87