Microchip® Advanced Software Framework

udp.c File Reference

User Datagram Protocol module.

#include "lwip/opt.h"
#include "lwip/udp.h"
#include "lwip/def.h"
#include "lwip/memp.h"
#include "lwip/inet_chksum.h"
#include "lwip/ip_addr.h"
#include "lwip/ip6.h"
#include "lwip/ip6_addr.h"
#include "lwip/netif.h"
#include "lwip/icmp.h"
#include "lwip/icmp6.h"
#include "lwip/stats.h"
#include "lwip/snmp.h"
#include "arch/perf.h"
#include "lwip/dhcp.h"
#include <string.h>

Macros

#define UDP_ENSURE_LOCAL_PORT_RANGE(port)   (((port) & ~UDP_LOCAL_PORT_RANGE_START) + UDP_LOCAL_PORT_RANGE_START)
 
#define UDP_LOCAL_PORT_RANGE_END   0xffff
 
#define UDP_LOCAL_PORT_RANGE_START   0xc000
 

Functions

err_t udp_bind (struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
 Bind an UDP PCB. More...
 
err_t udp_connect (struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
 Connect an UDP PCB. More...
 
void udp_disconnect (struct udp_pcb *pcb)
 Disconnect a UDP PCB. More...
 
void udp_init (void)
 Initialize this module. More...
 
void udp_input (struct pbuf *p, struct netif *inp)
 Process an incoming UDP datagram. More...
 
struct udp_pcbudp_new (void)
 Create a UDP PCB. More...
 
struct udp_pcbudp_new_ip6 (void)
 Create a UDP PCB for IPv6. More...
 
static u16_t udp_new_port (void)
 Allocate a new local UDP port. More...
 
void udp_recv (struct udp_pcb *pcb, udp_recv_fn recv, void *recv_arg)
 Set a receive callback for a UDP PCB. More...
 
void udp_remove (struct udp_pcb *pcb)
 Remove an UDP PCB. More...
 
err_t udp_send (struct udp_pcb *pcb, struct pbuf *p)
 Send data using UDP. More...
 
err_t udp_sendto (struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, u16_t dst_port)
 Send data to a specified address using UDP. More...
 
err_t udp_sendto_if (struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif)
 Send data to a specified address using UDP. More...
 
err_t udp_sendto_if_src (struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif, ip_addr_t *src_ip)
 Same as udp_sendto_if(), but with source address. More...
 

Variables

struct udp_pcbudp_pcbs
 
static u16_t udp_port = UDP_LOCAL_PORT_RANGE_START
 

#define UDP_ENSURE_LOCAL_PORT_RANGE (   port)    (((port) & ~UDP_LOCAL_PORT_RANGE_START) + UDP_LOCAL_PORT_RANGE_START)

Referenced by udp_init().

#define UDP_LOCAL_PORT_RANGE_END   0xffff

Referenced by udp_new_port().

#define UDP_LOCAL_PORT_RANGE_START   0xc000

Referenced by udp_new_port().

err_t udp_bind ( struct udp_pcb pcb,
ip_addr_t ipaddr,
u16_t  port 
)

Bind an UDP PCB.

Parameters
pcbUDP PCB to be bound with a local address ipaddr and port.
ipaddrlocal IP address to bind with. Use IP_ADDR_ANY to bind to all local interfaces.
portlocal UDP port to bind with. Use 0 to automatically bind to a random port between UDP_LOCAL_PORT_RANGE_START and UDP_LOCAL_PORT_RANGE_END.

ipaddr & port are expected to be in the same byte order as in the pcb.

Returns
lwIP error code.
  • ERR_OK. Successful. No error occurred.
  • ERR_USE. The specified ipaddr and port are already bound to by another UDP PCB.
See Also
udp_disconnect()

References ERR_OK, ERR_USE, ip_2_ipX, ip_get_option, IP_PCB_IPVER_EQ, ipX_addr_cmp, ipX_addr_debug_print, ipX_addr_isany, ipX_addr_set_ipaddr, udp_pcb::local_port, LWIP_ASSERT, LWIP_DBG_STATE, LWIP_DBG_TRACE, LWIP_DEBUGF, udp_pcb::next, NULL, PCB_ISIPV6, snmp_insert_udpidx_tree, SOF_REUSEADDR, U16_F, UDP_DEBUG, udp_new_port(), and udp_pcbs.

Referenced by dhcp_inform(), dhcp_start(), dns_alloc_random_port(), dns_init(), lwip_dhcpserver_start_threadsafe(), lwip_netconn_do_bind(), and udp_connect().

err_t udp_connect ( struct udp_pcb pcb,
ip_addr_t ipaddr,
u16_t  port 
)

Connect an UDP PCB.

This will associate the UDP PCB with the remote address.

Parameters
pcbUDP PCB to be connected with remote address ipaddr and port.
ipaddrremote IP address to connect with.
portremote UDP port to connect with.
Returns
lwIP error code

ipaddr & port are expected to be in the same byte order as in the pcb.

The udp pcb is bound to a random local port if not already bound.

See Also
udp_disconnect()

TODO: this functionality belongs in upper layers

References ERR_OK, ERR_RTE, udp_pcb::flags, ip4_addr_get_u32, netif::ip_addr, ip_addr_isany, ip_route(), ipX_2_ip, ipX_addr_copy, ipX_addr_debug_print, ipX_addr_set_any, ipX_addr_set_ipaddr, udp_pcb::local_port, LWIP_DBG_STATE, LWIP_DBG_TRACE, LWIP_DEBUGF, udp_pcb::next, NULL, PCB_ISIPV6, udp_pcb::remote_port, U16_F, udp_bind(), UDP_DEBUG, UDP_FLAGS_CONNECTED, udp_pcbs, and UDP_STATS_INC.

Referenced by dhcp_start(), and lwip_netconn_do_connect().

void udp_disconnect ( struct udp_pcb pcb)

Disconnect a UDP PCB.

Parameters
pcbthe udp pcb to disconnect.

References udp_pcb::flags, ipX_addr_set_any, PCB_ISIPV6, udp_pcb::remote_port, and UDP_FLAGS_CONNECTED.

Referenced by lwip_netconn_do_disconnect(), and lwip_tiny_dhcpserver_stop_threadsafe().

void udp_init ( void  )

Initialize this module.

References LWIP_RAND, UDP_ENSURE_LOCAL_PORT_RANGE, and udp_port.

Referenced by lwip_init().

void udp_input ( struct pbuf p,
struct netif inp 
)

Process an incoming UDP datagram.

Given an incoming UDP datagram (as a chain of pbufs) this function finds a corresponding UDP PCB and hands over the pbuf to the pcbs recv function. If no pcb is found or the datagram is incorrect, the pbuf is freed.

Parameters
ppbuf to be demultiplexed to a UDP PCB (p->payload pointing to the UDP header)
inpnetwork interface on which the datagram was received.

References netif::dhcp, DHCP_CLIENT_PORT, DHCP_SERVER_PORT, ERR_OK, udp_pcb::flags, icmp_port_unreach, udp_pcb::ip4, ip6_addr_cmp, ip6_addr_isany, ip6_addr_ismulticast, ip6_current_dest_addr, ip6_current_src_addr, netif::ip_addr, ip_addr_cmp, ip_addr_isbroadcast, ip_addr_ismulticast, ip_addr_netcmp, ip_current_dest_addr, ip_current_header, ip_current_header_proto, ip_current_header_tot_len, ip_current_is_v6, ip_current_src_addr, ip_get_option, IP_PCB_IPVER_INPUT_MATCH, IP_PROTO_UDP, IP_PROTO_UDPLITE, ipX_2_ip, ipX_2_ip6, ipX_addr_cmp, ipX_addr_debug_print, ipX_addr_isany, ipX_chksum_pseudo, ipX_chksum_pseudo_partial, ipX_current_dest_addr, ipX_current_src_addr, pbuf::len, udp_pcb::local_port, LWIP_ASSERT, LWIP_DBG_LEVEL_SERIOUS, LWIP_DBG_TRACE, LWIP_DEBUGF, LWIP_IGMP, LWIP_IPV6, netif_get_ip6_addr_match(), netif::netmask, udp_pcb::next, ntohs, NULL, pbuf::payload, pbuf_alloc(), pbuf_copy(), pbuf_free(), pbuf_header(), pbuf_header_force(), PBUF_RAM, PBUF_RAW, dhcp::pcb, PCB_ISIPV6, PERF_START, PERF_STOP, udp_pcb::recv, udp_pcb::recv_arg, udp_pcb::remote_port, snmp_inc_udpindatagrams, snmp_inc_udpinerrors, snmp_inc_udpnoports, SOF_BROADCAST, SOF_REUSEADDR, pbuf::tot_len, U16_F, UDP_DEBUG, udp_debug_print, UDP_FLAGS_CONNECTED, UDP_HLEN, udp_pcbs, and UDP_STATS_INC.

Referenced by ip6_input(), and ip_input().

struct udp_pcb* udp_new ( void  )

Create a UDP PCB.

Returns
The UDP PCB which was created. NULL if the PCB data structure could not be allocated.
See Also
udp_remove()

References memp_malloc(), and NULL.

Referenced by dhcp_inform(), dhcp_start(), dns_alloc_random_port(), dns_init(), lwip_dhcpserver_start_threadsafe(), pcb_new(), and udp_new_ip6().

struct udp_pcb* udp_new_ip6 ( void  )

Create a UDP PCB for IPv6.

Returns
The UDP PCB which was created. NULL if the PCB data structure could not be allocated.
See Also
udp_remove()

References ip_set_v6, and udp_new().

static u16_t udp_new_port ( void  )
static

Allocate a new local UDP port.

Returns
a new (free) local UDP port number

References udp_pcb::local_port, udp_pcb::next, NULL, UDP_LOCAL_PORT_RANGE_END, UDP_LOCAL_PORT_RANGE_START, udp_pcbs, and udp_port.

Referenced by udp_bind().

void udp_recv ( struct udp_pcb pcb,
udp_recv_fn  recv,
void recv_arg 
)

Set a receive callback for a UDP PCB.

This callback will be called when receiving a datagram for the pcb.

Parameters
pcbthe pcb for which to set the recv callback
recvfunction pointer of the callback function
recv_argadditional argument to pass to the callback function

References udp_pcb::ip4, udp_pcb::recv, recv(), and udp_pcb::recv_arg.

Referenced by dhcp_start(), dns_alloc_random_port(), dns_init(), lwip_dhcpserver_start_threadsafe(), and pcb_new().

void udp_remove ( struct udp_pcb pcb)

Remove an UDP PCB.

Parameters
pcbUDP PCB to be removed. The PCB is removed from the list of UDP PCB's and the data structure is freed from memory.
See Also
udp_new()

References memp_free(), udp_pcb::next, NULL, and snmp_delete_udpidx_tree.

Referenced by dhcp_inform(), dhcp_start(), dhcp_stop(), dns_alloc_random_port(), dns_call_found(), lwip_netconn_do_delconn(), and lwip_tiny_dhcpserver_stop_threadsafe().

err_t udp_send ( struct udp_pcb pcb,
struct pbuf p 
)

Send data using UDP.

Parameters
pcbUDP PCB used to send the data.
pchain of pbuf's to be sent.

The datagram will be sent to the current remote_ip & remote_port stored in pcb. If the pcb is not bound to a port, it will automatically be bound to a random port.

Returns
lwIP error code.
  • ERR_OK. Successful. No error occurred.
  • ERR_MEM. Out of memory.
  • ERR_RTE. Could not find route to destination address.
  • More errors could be returned by lower protocol layers.
See Also
udp_disconnect() udp_sendto()

References ipX_2_ip, udp_pcb::remote_port, and udp_sendto().

Referenced by lwip_netconn_do_send().

err_t udp_sendto ( struct udp_pcb pcb,
struct pbuf p,
ip_addr_t dst_ip,
u16_t  dst_port 
)

Send data to a specified address using UDP.

Parameters
pcbUDP PCB used to send the data.
pchain of pbuf's to be sent.
dst_ipDestination IP address.
dst_portDestination UDP port.

dst_ip & dst_port are expected to be in the same byte order as in the pcb.

If the PCB already has a remote address association, it will be restored after the data is sent.

Returns
lwIP error code (
See Also
udp_send for possible error codes)
udp_disconnect() udp_send()

Referenced by dns_send(), lwip_dhcp_server_fn(), lwip_netconn_do_send(), and udp_send().

err_t udp_sendto_if ( struct udp_pcb pcb,
struct pbuf p,
ip_addr_t dst_ip,
u16_t  dst_port,
struct netif netif 
)

Send data to a specified address using UDP.

The netif used for sending can be specified.

This function exists mainly for DHCP, to be able to send UDP packets on a netif that is still down.

Parameters
pcbUDP PCB used to send the data.
pchain of pbuf's to be sent.
dst_ipDestination IP address.
dst_portDestination UDP port.
netifthe netif used for sending.

dst_ip & dst_port are expected to be in the same byte order as in the pcb.

Returns
lwIP error code (
See Also
udp_send for possible error codes)
udp_disconnect() udp_send()

Referenced by dhcp_inform(), dhcp_rebind(), dhcp_reboot(), dhcp_release(), and dhcp_renew().

err_t udp_sendto_if_src ( struct udp_pcb pcb,
struct pbuf p,
ip_addr_t dst_ip,
u16_t  dst_port,
struct netif netif,
ip_addr_t src_ip 
)

Same as udp_sendto_if(), but with source address.

Referenced by dhcp_decline(), dhcp_discover(), and dhcp_select().

struct udp_pcb* udp_pcbs
u16_t udp_port = UDP_LOCAL_PORT_RANGE_START
static

Referenced by udp_init(), and udp_new_port().