3 * User Datagram Protocol module
7 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
10 * Redistribution and use in source and binary forms, with or without modification,
11 * are permitted provided that the following conditions are met:
13 * 1. Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
24 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
26 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
32 * This file is part of the lwIP TCP/IP stack.
34 * Author: Adam Dunkels <adam@sics.se>
41 * The code for the User Datagram Protocol UDP.
48 #include "lwip/memp.h"
49 #include "lwip/inet.h"
50 #include "lwip/ip_addr.h"
51 #include "lwip/netif.h"
53 #include "lwip/icmp.h"
55 #include "lwip/stats.h"
57 #include "arch/perf.h"
58 #include "lwip/snmp.h"
60 /* The list of UDP PCBs */
62 /* was static, but we may want to access this from a socket layer */
63 struct udp_pcb *udp_pcbs = NULL;
65 static struct udp_pcb *pcb_cache = NULL;
71 udp_pcbs = pcb_cache = NULL;
75 * Process an incoming UDP datagram.
77 * Given an incoming UDP datagram (as a chain of pbufs) this function
78 * finds a corresponding UDP PCB and
80 * @param pbuf pbuf to be demultiplexed to a UDP PCB.
81 * @param netif network interface on which the datagram was received.
85 udp_input(struct pbuf *p, struct netif *inp)
87 struct udp_hdr *udphdr;
93 struct udp_pcb *pcb_temp;
101 UDP_STATS_INC(udp.recv);
105 if (pbuf_header(p, -((s16_t)(UDP_HLEN + IPH_HL(iphdr) * 4)))) {
106 /* drop short packets */
107 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: short UDP datagram (%u bytes) discarded\n", p->tot_len));
108 UDP_STATS_INC(udp.lenerr);
109 UDP_STATS_INC(udp.drop);
110 snmp_inc_udpinerrors();
115 udphdr = (struct udp_hdr *)((u8_t *)p->payload - UDP_HLEN);
117 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %u\n", p->tot_len));
119 src = ntohs(udphdr->src);
120 dest = ntohs(udphdr->dest);
122 udp_debug_print(udphdr);
124 /* print the UDP source and destination */
125 LWIP_DEBUGF(UDP_DEBUG, ("udp (%u.%u.%u.%u, %u) <-- (%u.%u.%u.%u, %u)\n",
126 ip4_addr1(&iphdr->dest), ip4_addr2(&iphdr->dest),
127 ip4_addr3(&iphdr->dest), ip4_addr4(&iphdr->dest), ntohs(udphdr->dest),
128 ip4_addr1(&iphdr->src), ip4_addr2(&iphdr->src),
129 ip4_addr3(&iphdr->src), ip4_addr4(&iphdr->src), ntohs(udphdr->src)));
136 /* Iterate through the UDP pcb list for a fully matching pcb */
137 for(pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {
139 /* Iterate through the UDP pcb list for a fully matching pcb */
140 for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
141 #endif /* SO_REUSE */
142 /* print the PCB local and remote address */
143 LWIP_DEBUGF(UDP_DEBUG, ("pcb (%u.%u.%u.%u, %u) --- (%u.%u.%u.%u, %u)\n",
144 ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip),
145 ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port,
146 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
147 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));
149 /* PCB remote port matches UDP source port? */
150 if ((pcb->remote_port == src) &&
151 /* PCB local port matches UDP destination port? */
152 (pcb->local_port == dest) &&
153 /* accepting from any remote (source) IP address? or... */
154 (ip_addr_isany(&pcb->remote_ip) ||
155 /* PCB remote IP address matches UDP source IP address? */
156 ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
157 /* accepting on any local (netif) IP address? or... */
158 (ip_addr_isany(&pcb->local_ip) ||
159 /* PCB local IP address matches UDP destination IP address? */
160 ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
162 if(pcb->so_options & SOF_REUSEPORT) {
164 /* We processed one PCB already */
165 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB and SOF_REUSEPORT set.\n"));
167 /* First PCB with this address */
168 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: first PCB and SOF_REUSEPORT set.\n"));
174 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: reference counter on PBUF set to %i\n", p->ref));
177 /* We processed one PCB already */
178 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB but SOF_REUSEPORT not set !\n"));
181 #endif /* SO_REUSE */
185 /* no fully matching pcb found? then look for an unconnected pcb */
187 /* Iterate through the UDP PCB list for a pcb that matches
188 the local address. */
195 for(pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {
197 for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
198 #endif /* SO_REUSE */
199 LWIP_DEBUGF(UDP_DEBUG, ("pcb (%u.%u.%u.%u, %u) --- (%u.%u.%u.%u, %u)\n",
200 ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip),
201 ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port,
202 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
203 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));
205 if (((pcb->flags & UDP_FLAGS_CONNECTED) == 0) &&
206 /* destination port matches? */
207 (pcb->local_port == dest) &&
208 /* not bound to a specific (local) interface address? or... */
209 (ip_addr_isany(&pcb->local_ip) ||
210 /* ...matching interface address? */
211 ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
213 if(pcb->so_options & SOF_REUSEPORT) {
215 /* We processed one PCB already */
216 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB and SOF_REUSEPORT set.\n"));
218 /* First PCB with this address */
219 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: first PCB and SOF_REUSEPORT set.\n"));
225 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: reference counter on PBUF set to %i\n", p->ref));
228 /* We processed one PCB already */
229 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB but SOF_REUSEPORT not set !\n"));
232 #endif /* SO_REUSE */
238 /* Check checksum if this is a match or if it was directed at us. */
239 if (pcb != NULL || ip_addr_cmp(&inp->ip_addr, &iphdr->dest))
241 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: calculating checksum\n"));
242 pbuf_header(p, UDP_HLEN);
244 if (iphdr->nexthdr == IP_PROTO_UDPLITE) {
246 if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
248 /* Do the UDP Lite checksum */
249 #if CHECKSUM_CHECK_UDP
250 if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
251 (struct ip_addr *)&(iphdr->dest),
252 IP_PROTO_UDPLITE, ntohs(udphdr->len)) != 0) {
253 LWIP_DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
254 UDP_STATS_INC(udp.chkerr);
255 UDP_STATS_INC(udp.drop);
256 snmp_inc_udpinerrors();
262 #if CHECKSUM_CHECK_UDP
263 if (udphdr->chksum != 0) {
264 if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
265 (struct ip_addr *)&(iphdr->dest),
266 IP_PROTO_UDP, p->tot_len) != 0) {
267 LWIP_DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP datagram discarded due to failing checksum\n"));
269 UDP_STATS_INC(udp.chkerr);
270 UDP_STATS_INC(udp.drop);
271 snmp_inc_udpinerrors();
278 pbuf_header(p, -UDP_HLEN);
280 snmp_inc_udpindatagrams();
281 pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);
283 /* First socket should receive now */
284 if(reuse_port_1 || reuse_port_2) {
285 /* We want to search on next socket after receiving */
286 pcb_temp = pcb->next;
289 /* We are searching connected sockets */
294 /* We are searching unconnected sockets */
300 #endif /* SO_REUSE */
304 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: freeing PBUF with reference counter set to %i\n", p->ref));
308 #endif /* SO_REUSE */
309 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: not for us.\n"));
311 /* No match was found, send ICMP destination port unreachable unless
312 destination address was broadcast/multicast. */
314 if (!ip_addr_isbroadcast(&iphdr->dest, inp) &&
315 !ip_addr_ismulticast(&iphdr->dest)) {
317 /* adjust pbuf pointer */
319 icmp_dest_unreach(p, ICMP_DUR_PORT);
321 UDP_STATS_INC(udp.proterr);
322 UDP_STATS_INC(udp.drop);
323 snmp_inc_udpnoports();
331 PERF_STOP("udp_input");
335 * Send data to a specified address using UDP.
337 * @param pcb UDP PCB used to send the data.
338 * @param pbuf chain of pbuf's to be sent.
339 * @param dst_ip Destination IP address.
340 * @param dst_port Destination UDP port.
342 * If the PCB already has a remote address association, it will
343 * be restored after the data is sent.
345 * @return lwIP error code.
346 * - ERR_OK. Successful. No error occured.
347 * - ERR_MEM. Out of memory.
348 * - ERR_RTE. Could not find route to destination address.
350 * @see udp_disconnect() udp_send()
353 udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
354 struct ip_addr *dst_ip, u16_t dst_port)
357 struct ip_addr pcb_remote_ip;
358 u16_t pcb_remote_port;
359 /* remember remote peer address of PCB */
360 pcb_remote_ip.addr = pcb->remote_ip.addr;
361 pcb_remote_port = pcb->remote_port;
362 /* copy packet destination address to PCB remote peer address */
363 pcb->remote_ip.addr = dst_ip->addr;
364 pcb->remote_port = dst_port;
365 /* send to the packet destination address */
366 err = udp_send(pcb, p);
367 /* reset PCB remote peer address */
368 pcb->remote_ip.addr = pcb_remote_ip.addr;
369 pcb->remote_port = pcb_remote_port;
374 * Send data using UDP.
376 * @param pcb UDP PCB used to send the data.
377 * @param pbuf chain of pbuf's to be sent.
379 * @return lwIP error code.
380 * - ERR_OK. Successful. No error occured.
381 * - ERR_MEM. Out of memory.
382 * - ERR_RTE. Could not find route to destination address.
384 * @see udp_disconnect() udp_sendto()
387 udp_send(struct udp_pcb *pcb, struct pbuf *p)
389 struct udp_hdr *udphdr;
391 struct ip_addr *src_ip;
393 struct pbuf *q; /* q will be sent down the stack */
395 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_send\n"));
397 /* if the PCB is not yet bound to a port, bind it here */
398 if (pcb->local_port == 0) {
399 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: not yet bound to a port, binding now\n"));
400 err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
402 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: forced port bind failed\n"));
407 /* not enough space to add an UDP header to first pbuf in given p chain? */
408 if (pbuf_header(p, UDP_HLEN)) {
409 /* allocate header in a seperate new pbuf */
410 q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);
411 /* new header pbuf could not be allocated? */
413 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: could not allocate header\n"));
416 /* chain header q in front of given pbuf p */
418 /* { first pbuf q points to header pbuf } */
419 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
420 /* adding a header within p succeeded */
422 /* first pbuf q equals given pbuf */
424 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));
426 /* { q now represents the packet to be sent } */
428 udphdr->src = htons(pcb->local_port);
429 udphdr->dest = htons(pcb->remote_port);
430 /* in UDP, 0 checksum means 'no checksum' */
431 udphdr->chksum = 0x0000;
433 /* find the outgoing network interface for this packet */
434 if ((netif = ip_route(&(pcb->remote_ip))) == NULL) {
435 LWIP_DEBUGF(UDP_DEBUG | 1, ("udp_send: No route to 0x%lx\n", pcb->remote_ip.addr));
436 UDP_STATS_INC(udp.rterr);
439 /* PCB local address is IP_ANY_ADDR? */
440 if (ip_addr_isany(&pcb->local_ip)) {
441 /* use outgoing network interface IP address as source address */
442 src_ip = &(netif->ip_addr);
444 /* use UDP PCB local IP address as source address */
445 src_ip = &(pcb->local_ip);
448 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %u\n", q->tot_len));
450 /* UDP Lite protocol? */
451 if (pcb->flags & UDP_FLAGS_UDPLITE) {
452 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %u\n", q->tot_len));
453 /* set UDP message length in UDP header */
454 udphdr->len = htons(pcb->chksum_len);
455 /* calculate checksum */
457 udphdr->chksum = inet_chksum_pseudo(q, src_ip, &(pcb->remote_ip),
458 IP_PROTO_UDP, pcb->chksum_len);
459 /* chksum zero must become 0xffff, as zero means 'no checksum' */
460 if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
462 udphdr->chksum = 0x0000;
465 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));
466 err = ip_output_if (q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);
469 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %u\n", q->tot_len));
470 udphdr->len = htons(q->tot_len);
471 /* calculate checksum */
473 if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
474 udphdr->chksum = inet_chksum_pseudo(q, src_ip, &pcb->remote_ip, IP_PROTO_UDP, q->tot_len);
475 /* chksum zero must become 0xffff, as zero means 'no checksum' */
476 if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
479 udphdr->chksum = 0x0000;
481 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04x\n", udphdr->chksum));
482 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
484 err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);
486 /* TODO: must this be increased even if error occured? */
487 snmp_inc_udpoutdatagrams();
489 /* did we chain a seperate header pbuf earlier? */
491 /* free the header pbuf */
492 pbuf_free(q); q = NULL;
493 /* { p is still referenced by the caller, and will live on } */
496 UDP_STATS_INC(udp.xmit);
503 * @param pcb UDP PCB to be bound with a local address ipaddr and port.
504 * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to
505 * bind to all local interfaces.
506 * @param port local UDP port to bind with.
508 * @return lwIP error code.
509 * - ERR_OK. Successful. No error occured.
510 * - ERR_USE. The specified ipaddr and port are already bound to by
513 * @see udp_disconnect()
516 udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
518 struct udp_pcb *ipcb;
521 int reuse_port_all_set = 1;
522 #endif /* SO_REUSE */
523 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_bind(ipaddr = "));
524 ip_addr_debug_print(UDP_DEBUG, ipaddr);
525 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, (", port = %u)\n", port));
528 /* Check for double bind and rebind of the same pcb */
529 for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
530 /* is this UDP PCB already on active list? */
532 /* pcb may occur at most once in active list */
533 LWIP_ASSERT("rebind == 0", rebind == 0);
534 /* pcb already in list, just rebind */
539 /* this code does not allow upper layer to share a UDP port for
540 listening to broadcast or multicast traffic (See SO_REUSE_ADDR and
541 SO_REUSE_PORT under *BSD). TODO: See where it fits instead, OR
542 combine with implementation of UDP PCB flags. Leon Woestenberg. */
544 /* port matches that of PCB in list? */
545 else if ((ipcb->local_port == port) &&
546 /* IP address matches, or one is IP_ADDR_ANY? */
547 (ip_addr_isany(&(ipcb->local_ip)) ||
548 ip_addr_isany(ipaddr) ||
549 ip_addr_cmp(&(ipcb->local_ip), ipaddr))) {
550 /* other PCB already binds to this local IP and port */
551 LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: local port %u already bound by another pcb\n", port));
557 /* Search through list of PCB's.
559 If there is a PCB bound to specified port and IP_ADDR_ANY another PCB can be bound to the interface IP
560 or to the loopback address on the same port if SOF_REUSEADDR is set. Any combination of PCB's bound to
561 the same local port, but to one address out of {IP_ADDR_ANY, 127.0.0.1, interface IP} at a time is valid.
562 But no two PCB's bound to same local port and same local address is valid.
564 If SOF_REUSEPORT is set several PCB's can be bound to same local port and same local address also. But then
565 all PCB's must have the SOF_REUSEPORT option set.
567 When the two options aren't set and specified port is already bound, ERR_USE is returned saying that
568 address is already in use. */
569 else if (ipcb->local_port == port) {
570 if(ip_addr_cmp(&(ipcb->local_ip), ipaddr)) {
571 if(pcb->so_options & SOF_REUSEPORT) {
572 LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: in UDP PCB's SO_REUSEPORT set and same address.\n"));
573 reuse_port_all_set = (reuse_port_all_set && (ipcb->so_options & SOF_REUSEPORT));
576 LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: in UDP PCB's SO_REUSEPORT not set and same address.\n"));
580 else if((ip_addr_isany(ipaddr) && !ip_addr_isany(&(ipcb->local_ip))) ||
581 (!ip_addr_isany(ipaddr) && ip_addr_isany(&(ipcb->local_ip)))) {
582 if(!(pcb->so_options & SOF_REUSEADDR) && !(pcb->so_options & SOF_REUSEPORT)) {
583 LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: in UDP PCB's SO_REUSEPORT or SO_REUSEADDR not set and not the same address.\n"));
588 #endif /* SO_REUSE */
593 /* If SOF_REUSEPORT isn't set in all PCB's bound to specified port and local address specified then
594 {IP, port} can't be reused. */
595 if(!reuse_port_all_set) {
596 LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: not all sockets have SO_REUSEPORT set.\n"));
599 #endif /* SO_REUSE */
601 ip_addr_set(&pcb->local_ip, ipaddr);
602 /* no port specified? */
604 #ifndef UDP_LOCAL_PORT_RANGE_START
605 #define UDP_LOCAL_PORT_RANGE_START 4096
606 #define UDP_LOCAL_PORT_RANGE_END 0x7fff
608 port = UDP_LOCAL_PORT_RANGE_START;
610 while ((ipcb != NULL) && (port != UDP_LOCAL_PORT_RANGE_END)) {
611 if (ipcb->local_port == port) {
618 /* no more ports available in local range */
619 LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n"));
623 pcb->local_port = port;
624 /* pcb not active yet? */
626 /* place the PCB on the active list if not already there */
627 pcb->next = udp_pcbs;
630 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_bind: bound to %u.%u.%u.%u, port %u\n",
631 (unsigned int)(ntohl(pcb->local_ip.addr) >> 24 & 0xff),
632 (unsigned int)(ntohl(pcb->local_ip.addr) >> 16 & 0xff),
633 (unsigned int)(ntohl(pcb->local_ip.addr) >> 8 & 0xff),
634 (unsigned int)(ntohl(pcb->local_ip.addr) & 0xff), pcb->local_port));
638 * Connect an UDP PCB.
640 * This will associate the UDP PCB with the remote address.
642 * @param pcb UDP PCB to be connected with remote address ipaddr and port.
643 * @param ipaddr remote IP address to connect with.
644 * @param port remote UDP port to connect with.
646 * @return lwIP error code
648 * @see udp_disconnect()
651 udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
653 struct udp_pcb *ipcb;
655 if (pcb->local_port == 0) {
656 err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
661 ip_addr_set(&pcb->remote_ip, ipaddr);
662 pcb->remote_port = port;
663 pcb->flags |= UDP_FLAGS_CONNECTED;
664 /** TODO: this functionality belongs in upper layers */
666 /* Nail down local IP for netconn_addr()/getsockname() */
667 if (ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) {
670 if ((netif = ip_route(&(pcb->remote_ip))) == NULL) {
671 LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr));
672 UDP_STATS_INC(udp.rterr);
675 /** TODO: this will bind the udp pcb locally, to the interface which
676 is used to route output packets to the remote address. However, we
677 might want to accept incoming packets on any interface! */
678 pcb->local_ip = netif->ip_addr;
679 } else if (ip_addr_isany(&pcb->remote_ip)) {
680 pcb->local_ip.addr = 0;
683 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_connect: connected to %u.%u.%u.%u, port %u\n",
684 (unsigned int)(ntohl(pcb->remote_ip.addr) >> 24 & 0xff),
685 (unsigned int)(ntohl(pcb->remote_ip.addr) >> 16 & 0xff),
686 (unsigned int)(ntohl(pcb->remote_ip.addr) >> 8 & 0xff),
687 (unsigned int)(ntohl(pcb->remote_ip.addr) & 0xff), pcb->remote_port));
689 /* Insert UDP PCB into the list of active UDP PCBs. */
690 for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
692 /* already on the list, just return */
696 /* PCB not yet on the list, add PCB now */
697 pcb->next = udp_pcbs;
703 udp_disconnect(struct udp_pcb *pcb)
705 /* reset remote address association */
706 ip_addr_set(&pcb->remote_ip, IP_ADDR_ANY);
707 pcb->remote_port = 0;
708 /* mark PCB as unconnected */
709 pcb->flags &= ~UDP_FLAGS_CONNECTED;
713 udp_recv(struct udp_pcb *pcb,
714 void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p,
715 struct ip_addr *addr, u16_t port),
718 /* remember recv() callback and user data */
720 pcb->recv_arg = recv_arg;
725 * @param pcb UDP PCB to be removed. The PCB is removed from the list of
726 * UDP PCB's and the data structure is freed from memory.
731 udp_remove(struct udp_pcb *pcb)
733 struct udp_pcb *pcb2;
734 /* pcb to be removed is first in list? */
735 if (udp_pcbs == pcb) {
736 /* make list start at 2nd pcb */
737 udp_pcbs = udp_pcbs->next;
738 /* pcb not 1st in list */
739 } else for(pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
740 /* find pcb in udp_pcbs list */
741 if (pcb2->next != NULL && pcb2->next == pcb) {
742 /* remove pcb from list */
743 pcb2->next = pcb->next;
746 memp_free(MEMP_UDP_PCB, pcb);
751 * @return The UDP PCB which was created. NULL if the PCB data structure
752 * could not be allocated.
759 pcb = memp_malloc(MEMP_UDP_PCB);
760 /* could allocate UDP PCB? */
762 /* initialize PCB to all zeroes */
763 memset(pcb, 0, sizeof(struct udp_pcb));
773 udp_debug_print(struct udp_hdr *udphdr)
775 LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n"));
776 LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
777 LWIP_DEBUGF(UDP_DEBUG, ("| %5u | %5u | (src port, dest port)\n",
778 ntohs(udphdr->src), ntohs(udphdr->dest)));
779 LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
780 LWIP_DEBUGF(UDP_DEBUG, ("| %5u | 0x%04x | (len, chksum)\n",
781 ntohs(udphdr->len), ntohs(udphdr->chksum)));
782 LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
785 #endif /* UDP_DEBUG */
787 #endif /* LWIP_UDP */