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.
50 #include "lwip/memp.h"
51 #include "lwip/inet.h"
52 #include "lwip/ip_addr.h"
53 #include "lwip/netif.h"
55 #include "lwip/icmp.h"
57 #include "lwip/stats.h"
59 #include "arch/perf.h"
60 #include "lwip/snmp.h"
62 /* The list of UDP PCBs */
64 /* was static, but we may want to access this from a socket layer */
65 struct udp_pcb *udp_pcbs = NULL;
67 static struct udp_pcb *pcb_cache = NULL;
73 udp_pcbs = pcb_cache = NULL;
77 * Process an incoming UDP datagram.
79 * Given an incoming UDP datagram (as a chain of pbufs) this function
80 * finds a corresponding UDP PCB and
82 * @param pbuf pbuf to be demultiplexed to a UDP PCB.
83 * @param netif network interface on which the datagram was received.
87 udp_input(struct pbuf *p, struct netif *inp)
89 struct udp_hdr *udphdr;
95 struct udp_pcb *pcb_temp;
103 UDP_STATS_INC(udp.recv);
107 if (pbuf_header(p, -((s16_t)(UDP_HLEN + IPH_HL(iphdr) * 4)))) {
108 /* drop short packets */
109 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: short UDP datagram (%u bytes) discarded\n", p->tot_len));
110 UDP_STATS_INC(udp.lenerr);
111 UDP_STATS_INC(udp.drop);
112 snmp_inc_udpinerrors();
117 udphdr = (struct udp_hdr *)((u8_t *)p->payload - UDP_HLEN);
119 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %u\n", p->tot_len));
121 src = ntohs(udphdr->src);
122 dest = ntohs(udphdr->dest);
124 udp_debug_print(udphdr);
126 /* print the UDP source and destination */
127 LWIP_DEBUGF(UDP_DEBUG, ("udp (%u.%u.%u.%u, %u) <-- (%u.%u.%u.%u, %u)\n",
128 ip4_addr1(&iphdr->dest), ip4_addr2(&iphdr->dest),
129 ip4_addr3(&iphdr->dest), ip4_addr4(&iphdr->dest), ntohs(udphdr->dest),
130 ip4_addr1(&iphdr->src), ip4_addr2(&iphdr->src),
131 ip4_addr3(&iphdr->src), ip4_addr4(&iphdr->src), ntohs(udphdr->src)));
138 /* Iterate through the UDP pcb list for a fully matching pcb */
139 for (pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {
141 /* Iterate through the UDP pcb list for a fully matching pcb */
142 for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
143 #endif /* SO_REUSE */
144 /* print the PCB local and remote address */
145 LWIP_DEBUGF(UDP_DEBUG, ("pcb (%u.%u.%u.%u, %u) --- (%u.%u.%u.%u, %u)\n",
146 ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip),
147 ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port,
148 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
149 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));
151 /* PCB remote port matches UDP source port? */
152 if ((pcb->remote_port == src) &&
153 /* PCB local port matches UDP destination port? */
154 (pcb->local_port == dest) &&
155 /* accepting from any remote (source) IP address? or... */
156 (ip_addr_isany(&pcb->remote_ip) ||
157 /* PCB remote IP address matches UDP source IP address? */
158 ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
159 /* accepting on any local (netif) IP address? or... */
160 (ip_addr_isany(&pcb->local_ip) ||
161 /* PCB local IP address matches UDP destination IP address? */
162 ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
164 if (pcb->so_options & SOF_REUSEPORT) {
166 /* We processed one PCB already */
167 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB and SOF_REUSEPORT set.\n"));
169 /* First PCB with this address */
170 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: first PCB and SOF_REUSEPORT set.\n"));
176 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: reference counter on PBUF set to %i\n", p->ref));
179 /* We processed one PCB already */
180 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB but SOF_REUSEPORT not set !\n"));
183 #endif /* SO_REUSE */
187 /* no fully matching pcb found? then look for an unconnected pcb */
189 /* Iterate through the UDP PCB list for a pcb that matches
190 the local address. */
197 for (pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {
199 for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
200 #endif /* SO_REUSE */
201 LWIP_DEBUGF(UDP_DEBUG, ("pcb (%u.%u.%u.%u, %u) --- (%u.%u.%u.%u, %u)\n",
202 ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip),
203 ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port,
204 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
205 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));
207 if (((pcb->flags & UDP_FLAGS_CONNECTED) == 0) &&
208 /* destination port matches? */
209 (pcb->local_port == dest) &&
210 /* not bound to a specific (local) interface address? or... */
211 (ip_addr_isany(&pcb->local_ip) ||
212 /* ...matching interface address? */
213 ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
215 if (pcb->so_options & SOF_REUSEPORT) {
217 /* We processed one PCB already */
218 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB and SOF_REUSEPORT set.\n"));
220 /* First PCB with this address */
221 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: first PCB and SOF_REUSEPORT set.\n"));
227 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: reference counter on PBUF set to %i\n", p->ref));
230 /* We processed one PCB already */
231 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB but SOF_REUSEPORT not set !\n"));
234 #endif /* SO_REUSE */
240 /* Check checksum if this is a match or if it was directed at us. */
241 if (pcb != NULL || ip_addr_cmp(&inp->ip_addr, &iphdr->dest))
243 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: calculating checksum\n"));
244 pbuf_header(p, UDP_HLEN);
246 if (iphdr->nexthdr == IP_PROTO_UDPLITE) {
248 if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
250 /* Do the UDP Lite checksum */
251 #if CHECKSUM_CHECK_UDP
252 if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
253 (struct ip_addr *)&(iphdr->dest),
254 IP_PROTO_UDPLITE, ntohs(udphdr->len)) != 0) {
255 LWIP_DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
256 UDP_STATS_INC(udp.chkerr);
257 UDP_STATS_INC(udp.drop);
258 snmp_inc_udpinerrors();
264 #if CHECKSUM_CHECK_UDP
265 if (udphdr->chksum != 0) {
266 if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
267 (struct ip_addr *)&(iphdr->dest),
268 IP_PROTO_UDP, p->tot_len) != 0) {
269 LWIP_DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP datagram discarded due to failing checksum\n"));
271 UDP_STATS_INC(udp.chkerr);
272 UDP_STATS_INC(udp.drop);
273 snmp_inc_udpinerrors();
280 pbuf_header(p, -UDP_HLEN);
282 snmp_inc_udpindatagrams();
283 pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);
285 /* First socket should receive now */
286 if(reuse_port_1 || reuse_port_2) {
287 /* We want to search on next socket after receiving */
288 pcb_temp = pcb->next;
291 /* We are searching connected sockets */
296 /* We are searching unconnected sockets */
302 #endif /* SO_REUSE */
306 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: freeing PBUF with reference counter set to %i\n", p->ref));
310 #endif /* SO_REUSE */
311 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: not for us.\n"));
313 /* No match was found, send ICMP destination port unreachable unless
314 destination address was broadcast/multicast. */
316 if (!ip_addr_isbroadcast(&iphdr->dest, inp) &&
317 !ip_addr_ismulticast(&iphdr->dest)) {
319 /* adjust pbuf pointer */
321 icmp_dest_unreach(p, ICMP_DUR_PORT);
323 UDP_STATS_INC(udp.proterr);
324 UDP_STATS_INC(udp.drop);
325 snmp_inc_udpnoports();
333 PERF_STOP("udp_input");
337 * Send data to a specified address using UDP.
339 * @param pcb UDP PCB used to send the data.
340 * @param pbuf chain of pbuf's to be sent.
341 * @param dst_ip Destination IP address.
342 * @param dst_port Destination UDP port.
344 * If the PCB already has a remote address association, it will
345 * be restored after the data is sent.
347 * @return lwIP error code.
348 * - ERR_OK. Successful. No error occured.
349 * - ERR_MEM. Out of memory.
350 * - ERR_RTE. Could not find route to destination address.
352 * @see udp_disconnect() udp_send()
355 udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
356 struct ip_addr *dst_ip, u16_t dst_port)
359 /* temporary space for current PCB remote address */
360 struct ip_addr pcb_remote_ip;
361 u16_t pcb_remote_port;
362 /* remember current remote peer address of PCB */
363 pcb_remote_ip.addr = pcb->remote_ip.addr;
364 pcb_remote_port = pcb->remote_port;
365 /* copy packet destination address to PCB remote peer address */
366 pcb->remote_ip.addr = dst_ip->addr;
367 pcb->remote_port = dst_port;
368 /* send to the packet destination address */
369 err = udp_send(pcb, p);
370 /* restore PCB remote peer address */
371 pcb->remote_ip.addr = pcb_remote_ip.addr;
372 pcb->remote_port = pcb_remote_port;
377 * Send data using UDP.
379 * @param pcb UDP PCB used to send the data.
380 * @param pbuf chain of pbuf's to be sent.
382 * @return lwIP error code.
383 * - ERR_OK. Successful. No error occured.
384 * - ERR_MEM. Out of memory.
385 * - ERR_RTE. Could not find route to destination address.
387 * @see udp_disconnect() udp_sendto()
390 udp_send(struct udp_pcb *pcb, struct pbuf *p)
392 struct udp_hdr *udphdr;
394 struct ip_addr *src_ip;
396 struct pbuf *q; /* q will be sent down the stack */
398 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_send\n"));
400 /* if the PCB is not yet bound to a port, bind it here */
401 if (pcb->local_port == 0) {
402 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: not yet bound to a port, binding now\n"));
403 err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
405 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: forced port bind failed\n"));
410 /* not enough space to add an UDP header to first pbuf in given p chain? */
411 if (pbuf_header(p, UDP_HLEN)) {
412 /* allocate header in a seperate new pbuf */
413 q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);
414 /* new header pbuf could not be allocated? */
416 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: could not allocate header\n"));
419 /* chain header q in front of given pbuf p */
421 /* { first pbuf q points to header pbuf } */
422 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
423 /* adding a header within p succeeded */
425 /* first pbuf q equals given pbuf */
427 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));
429 /* { q now represents the packet to be sent } */
431 udphdr->src = htons(pcb->local_port);
432 udphdr->dest = htons(pcb->remote_port);
433 /* in UDP, 0 checksum means 'no checksum' */
434 udphdr->chksum = 0x0000;
436 /* find the outgoing network interface for this packet */
437 netif = ip_route(&(pcb->remote_ip));
438 /* no outgoing network interface could be found? */
440 LWIP_DEBUGF(UDP_DEBUG | 1, ("udp_send: No route to 0x%lx\n", pcb->remote_ip.addr));
441 UDP_STATS_INC(udp.rterr);
444 /* PCB local address is IP_ANY_ADDR? */
445 if (ip_addr_isany(&pcb->local_ip)) {
446 /* use outgoing network interface IP address as source address */
447 src_ip = &(netif->ip_addr);
449 /* use UDP PCB local IP address as source address */
450 src_ip = &(pcb->local_ip);
453 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %u\n", q->tot_len));
455 /* UDP Lite protocol? */
456 if (pcb->flags & UDP_FLAGS_UDPLITE) {
457 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %u\n", q->tot_len));
458 /* set UDP message length in UDP header */
459 udphdr->len = htons(pcb->chksum_len);
460 /* calculate checksum */
462 udphdr->chksum = inet_chksum_pseudo(q, src_ip, &(pcb->remote_ip),
463 IP_PROTO_UDP, pcb->chksum_len);
464 /* chksum zero must become 0xffff, as zero means 'no checksum' */
465 if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
467 udphdr->chksum = 0x0000;
470 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));
471 err = ip_output_if (q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);
474 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %u\n", q->tot_len));
475 udphdr->len = htons(q->tot_len);
476 /* calculate checksum */
478 if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
479 udphdr->chksum = inet_chksum_pseudo(q, src_ip, &pcb->remote_ip, IP_PROTO_UDP, q->tot_len);
480 /* chksum zero must become 0xffff, as zero means 'no checksum' */
481 if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
484 udphdr->chksum = 0x0000;
486 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04x\n", udphdr->chksum));
487 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
489 err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);
491 /* TODO: must this be increased even if error occured? */
492 snmp_inc_udpoutdatagrams();
494 /* did we chain a seperate header pbuf earlier? */
496 /* free the header pbuf */
497 pbuf_free(q); q = NULL;
498 /* { p is still referenced by the caller, and will live on } */
501 UDP_STATS_INC(udp.xmit);
508 * @param pcb UDP PCB to be bound with a local address ipaddr and port.
509 * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to
510 * bind to all local interfaces.
511 * @param port local UDP port to bind with.
513 * @return lwIP error code.
514 * - ERR_OK. Successful. No error occured.
515 * - ERR_USE. The specified ipaddr and port are already bound to by
518 * @see udp_disconnect()
521 udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
523 struct udp_pcb *ipcb;
526 int reuse_port_all_set = 1;
527 #endif /* SO_REUSE */
528 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_bind(ipaddr = "));
529 ip_addr_debug_print(UDP_DEBUG, ipaddr);
530 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, (", port = %u)\n", port));
533 /* Check for double bind and rebind of the same pcb */
534 for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
535 /* is this UDP PCB already on active list? */
537 /* pcb may occur at most once in active list */
538 LWIP_ASSERT("rebind == 0", rebind == 0);
539 /* pcb already in list, just rebind */
544 /* this code does not allow upper layer to share a UDP port for
545 listening to broadcast or multicast traffic (See SO_REUSE_ADDR and
546 SO_REUSE_PORT under *BSD). TODO: See where it fits instead, OR
547 combine with implementation of UDP PCB flags. Leon Woestenberg. */
549 /* port matches that of PCB in list? */
550 else if ((ipcb->local_port == port) &&
551 /* IP address matches, or one is IP_ADDR_ANY? */
552 (ip_addr_isany(&(ipcb->local_ip)) ||
553 ip_addr_isany(ipaddr) ||
554 ip_addr_cmp(&(ipcb->local_ip), ipaddr))) {
555 /* other PCB already binds to this local IP and port */
556 LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: local port %u already bound by another pcb\n", port));
562 /* Search through list of PCB's.
564 If there is a PCB bound to specified port and IP_ADDR_ANY another PCB can be bound to the interface IP
565 or to the loopback address on the same port if SOF_REUSEADDR is set. Any combination of PCB's bound to
566 the same local port, but to one address out of {IP_ADDR_ANY, 127.0.0.1, interface IP} at a time is valid.
567 But no two PCB's bound to same local port and same local address is valid.
569 If SOF_REUSEPORT is set several PCB's can be bound to same local port and same local address also. But then
570 all PCB's must have the SOF_REUSEPORT option set.
572 When the two options aren't set and specified port is already bound, ERR_USE is returned saying that
573 address is already in use. */
574 else if (ipcb->local_port == port) {
575 if(ip_addr_cmp(&(ipcb->local_ip), ipaddr)) {
576 if(pcb->so_options & SOF_REUSEPORT) {
577 LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: in UDP PCB's SO_REUSEPORT set and same address.\n"));
578 reuse_port_all_set = (reuse_port_all_set && (ipcb->so_options & SOF_REUSEPORT));
581 LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: in UDP PCB's SO_REUSEPORT not set and same address.\n"));
585 else if((ip_addr_isany(ipaddr) && !ip_addr_isany(&(ipcb->local_ip))) ||
586 (!ip_addr_isany(ipaddr) && ip_addr_isany(&(ipcb->local_ip)))) {
587 if(!(pcb->so_options & SOF_REUSEADDR) && !(pcb->so_options & SOF_REUSEPORT)) {
588 LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: in UDP PCB's SO_REUSEPORT or SO_REUSEADDR not set and not the same address.\n"));
593 #endif /* SO_REUSE */
598 /* If SOF_REUSEPORT isn't set in all PCB's bound to specified port and local address specified then
599 {IP, port} can't be reused. */
600 if(!reuse_port_all_set) {
601 LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: not all sockets have SO_REUSEPORT set.\n"));
604 #endif /* SO_REUSE */
606 ip_addr_set(&pcb->local_ip, ipaddr);
607 /* no port specified? */
609 #ifndef UDP_LOCAL_PORT_RANGE_START
610 #define UDP_LOCAL_PORT_RANGE_START 4096
611 #define UDP_LOCAL_PORT_RANGE_END 0x7fff
613 port = UDP_LOCAL_PORT_RANGE_START;
615 while ((ipcb != NULL) && (port != UDP_LOCAL_PORT_RANGE_END)) {
616 if (ipcb->local_port == port) {
623 /* no more ports available in local range */
624 LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n"));
628 pcb->local_port = port;
629 /* pcb not active yet? */
631 /* place the PCB on the active list if not already there */
632 pcb->next = udp_pcbs;
635 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_bind: bound to %u.%u.%u.%u, port %u\n",
636 (unsigned int)(ntohl(pcb->local_ip.addr) >> 24 & 0xff),
637 (unsigned int)(ntohl(pcb->local_ip.addr) >> 16 & 0xff),
638 (unsigned int)(ntohl(pcb->local_ip.addr) >> 8 & 0xff),
639 (unsigned int)(ntohl(pcb->local_ip.addr) & 0xff), pcb->local_port));
643 * Connect an UDP PCB.
645 * This will associate the UDP PCB with the remote address.
647 * @param pcb UDP PCB to be connected with remote address ipaddr and port.
648 * @param ipaddr remote IP address to connect with.
649 * @param port remote UDP port to connect with.
651 * @return lwIP error code
653 * @see udp_disconnect()
656 udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
658 struct udp_pcb *ipcb;
660 if (pcb->local_port == 0) {
661 err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
666 ip_addr_set(&pcb->remote_ip, ipaddr);
667 pcb->remote_port = port;
668 pcb->flags |= UDP_FLAGS_CONNECTED;
669 /** TODO: this functionality belongs in upper layers */
671 /* Nail down local IP for netconn_addr()/getsockname() */
672 if (ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) {
675 if ((netif = ip_route(&(pcb->remote_ip))) == NULL) {
676 LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr));
677 UDP_STATS_INC(udp.rterr);
680 /** TODO: this will bind the udp pcb locally, to the interface which
681 is used to route output packets to the remote address. However, we
682 might want to accept incoming packets on any interface! */
683 pcb->local_ip = netif->ip_addr;
684 } else if (ip_addr_isany(&pcb->remote_ip)) {
685 pcb->local_ip.addr = 0;
688 LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_connect: connected to %u.%u.%u.%u, port %u\n",
689 (unsigned int)(ntohl(pcb->remote_ip.addr) >> 24 & 0xff),
690 (unsigned int)(ntohl(pcb->remote_ip.addr) >> 16 & 0xff),
691 (unsigned int)(ntohl(pcb->remote_ip.addr) >> 8 & 0xff),
692 (unsigned int)(ntohl(pcb->remote_ip.addr) & 0xff), pcb->remote_port));
694 /* Insert UDP PCB into the list of active UDP PCBs. */
695 for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
697 /* already on the list, just return */
701 /* PCB not yet on the list, add PCB now */
702 pcb->next = udp_pcbs;
708 udp_disconnect(struct udp_pcb *pcb)
710 /* reset remote address association */
711 ip_addr_set(&pcb->remote_ip, IP_ADDR_ANY);
712 pcb->remote_port = 0;
713 /* mark PCB as unconnected */
714 pcb->flags &= ~UDP_FLAGS_CONNECTED;
718 udp_recv(struct udp_pcb *pcb,
719 void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p,
720 struct ip_addr *addr, u16_t port),
723 /* remember recv() callback and user data */
725 pcb->recv_arg = recv_arg;
730 * @param pcb UDP PCB to be removed. The PCB is removed from the list of
731 * UDP PCB's and the data structure is freed from memory.
736 udp_remove(struct udp_pcb *pcb)
738 struct udp_pcb *pcb2;
739 /* pcb to be removed is first in list? */
740 if (udp_pcbs == pcb) {
741 /* make list start at 2nd pcb */
742 udp_pcbs = udp_pcbs->next;
743 /* pcb not 1st in list */
744 } else for(pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
745 /* find pcb in udp_pcbs list */
746 if (pcb2->next != NULL && pcb2->next == pcb) {
747 /* remove pcb from list */
748 pcb2->next = pcb->next;
751 memp_free(MEMP_UDP_PCB, pcb);
756 * @return The UDP PCB which was created. NULL if the PCB data structure
757 * could not be allocated.
764 pcb = memp_malloc(MEMP_UDP_PCB);
765 /* could allocate UDP PCB? */
767 /* initialize PCB to all zeroes */
768 memset(pcb, 0, sizeof(struct udp_pcb));
778 udp_debug_print(struct udp_hdr *udphdr)
780 LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n"));
781 LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
782 LWIP_DEBUGF(UDP_DEBUG, ("| %5u | %5u | (src port, dest port)\n",
783 ntohs(udphdr->src), ntohs(udphdr->dest)));
784 LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
785 LWIP_DEBUGF(UDP_DEBUG, ("| %5u | 0x%04x | (len, chksum)\n",
786 ntohs(udphdr->len), ntohs(udphdr->chksum)));
787 LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
790 #endif /* UDP_DEBUG */
792 #endif /* LWIP_UDP */