3 * User Datagram Protocol module
7 * Copyright (c) 2001-2003 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/netif.h"
52 #include "lwip/icmp.h"
53 #include "lwip/ip_addr.h"
55 #include "lwip/stats.h"
57 #include "lwip/snmp.h"
63 /* The list of UDP PCBs */
65 /* was static, but we may want to access this from a socket layer */
66 struct udp_pcb
*udp_pcbs
= NULL
;
68 static struct udp_pcb
*pcb_cache
= NULL
;
74 udp_pcbs
= pcb_cache
= NULL
;
80 * An experimental feature that will be changed in future versions. Do
81 * not depend on it yet...
86 udp_lookup(struct ip_hdr
*iphdr
, struct netif
*inp
)
89 struct udp_hdr
*udphdr
;
94 udphdr
= (struct udp_hdr
*)(u8_t
*)iphdr
+ IPH_HL(iphdr
) * 4;
96 src
= ntohs(udphdr
->src
);
97 dest
= ntohs(udphdr
->dest
);
101 pcb
->remote_port
== src
&&
102 pcb
->local_port
== dest
&&
103 (ip_addr_isany(&pcb
->remote_ip
) ||
104 ip_addr_cmp(&(pcb
->remote_ip
), &(iphdr
->src
))) &&
105 (ip_addr_isany(&pcb
->local_ip
) ||
106 ip_addr_cmp(&(pcb
->local_ip
), &(iphdr
->dest
)))) {
110 for(pcb
= udp_pcbs
; pcb
!= NULL
; pcb
= pcb
->next
) {
111 if (pcb
->remote_port
== src
&&
112 pcb
->local_port
== dest
&&
113 (ip_addr_isany(&pcb
->remote_ip
) ||
114 ip_addr_cmp(&(pcb
->remote_ip
), &(iphdr
->src
))) &&
115 (ip_addr_isany(&pcb
->local_ip
) ||
116 ip_addr_cmp(&(pcb
->local_ip
), &(iphdr
->dest
)))) {
123 for(pcb
= udp_pcbs
; pcb
!= NULL
; pcb
= pcb
->next
) {
124 if (pcb
->remote_port
== 0 &&
125 pcb
->local_port
== dest
&&
126 (ip_addr_isany(&pcb
->remote_ip
) ||
127 ip_addr_cmp(&(pcb
->remote_ip
), &(iphdr
->src
))) &&
128 (ip_addr_isany(&pcb
->local_ip
) ||
129 ip_addr_cmp(&(pcb
->local_ip
), &(iphdr
->dest
)))) {
144 #endif /* LWIP_DEBUG */
146 * Process an incoming UDP datagram.
148 * Given an incoming UDP datagram (as a chain of pbufs) this function
149 * finds a corresponding UDP PCB and
151 * @param pbuf pbuf to be demultiplexed to a UDP PCB.
152 * @param netif network interface on which the datagram was received.
156 udp_input(struct pbuf
*p
, struct netif
*inp
)
158 struct udp_hdr
*udphdr
;
160 struct ip_hdr
*iphdr
;
164 struct udp_pcb
*pcb_temp
;
166 int reuse_port_1
= 0;
167 int reuse_port_2
= 0;
168 #endif /* SO_REUSE */
170 UDP_STATS_INC(udp
.recv
);
174 if (pbuf_header(p
, -((s16_t
)(UDP_HLEN
+ IPH_HL(iphdr
) * 4)))) {
175 /* drop short packets */
176 LWIP_DEBUGF(UDP_DEBUG
, ("udp_input: short UDP datagram (%u bytes) discarded\n", p
->tot_len
));
177 UDP_STATS_INC(udp
.lenerr
);
178 UDP_STATS_INC(udp
.drop
);
179 snmp_inc_udpinerrors();
184 udphdr
= (struct udp_hdr
*)((u8_t
*)p
->payload
- UDP_HLEN
);
186 LWIP_DEBUGF(UDP_DEBUG
, ("udp_input: received datagram of length %u\n", p
->tot_len
));
188 src
= ntohs(udphdr
->src
);
189 dest
= ntohs(udphdr
->dest
);
191 udp_debug_print(udphdr
);
193 /* print the UDP source and destination */
194 LWIP_DEBUGF(UDP_DEBUG
, ("udp (%u.%u.%u.%u, %u) <-- (%u.%u.%u.%u, %u)\n",
195 ip4_addr1(&iphdr
->dest
), ip4_addr2(&iphdr
->dest
),
196 ip4_addr3(&iphdr
->dest
), ip4_addr4(&iphdr
->dest
), ntohs(udphdr
->dest
),
197 ip4_addr1(&iphdr
->src
), ip4_addr2(&iphdr
->src
),
198 ip4_addr3(&iphdr
->src
), ip4_addr4(&iphdr
->src
), ntohs(udphdr
->src
)));
205 /* Iterate through the UDP pcb list for a fully matching pcb */
206 for(pcb
= pcb_temp
; pcb
!= NULL
; pcb
= pcb
->next
) {
208 /* Iterate through the UDP pcb list for a fully matching pcb */
209 for(pcb
= udp_pcbs
; pcb
!= NULL
; pcb
= pcb
->next
) {
210 #endif /* SO_REUSE */
211 /* print the PCB local and remote address */
212 LWIP_DEBUGF(UDP_DEBUG
, ("pcb (%u.%u.%u.%u, %u) --- (%u.%u.%u.%u, %u)\n",
213 ip4_addr1(&pcb
->local_ip
), ip4_addr2(&pcb
->local_ip
),
214 ip4_addr3(&pcb
->local_ip
), ip4_addr4(&pcb
->local_ip
), pcb
->local_port
,
215 ip4_addr1(&pcb
->remote_ip
), ip4_addr2(&pcb
->remote_ip
),
216 ip4_addr3(&pcb
->remote_ip
), ip4_addr4(&pcb
->remote_ip
), pcb
->remote_port
));
218 /* PCB remote port matches UDP source port? */
219 if ((pcb
->remote_port
== src
) &&
220 /* PCB local port matches UDP destination port? */
221 (pcb
->local_port
== dest
) &&
222 /* accepting from any remote (source) IP address? or... */
223 (ip_addr_isany(&pcb
->remote_ip
) ||
224 /* PCB remote IP address matches UDP source IP address? */
225 ip_addr_cmp(&(pcb
->remote_ip
), &(iphdr
->src
))) &&
226 /* accepting on any local (netif) IP address? or... */
227 (ip_addr_isany(&pcb
->local_ip
) ||
228 /* PCB local IP address matches UDP destination IP address? */
229 ip_addr_cmp(&(pcb
->local_ip
), &(iphdr
->dest
)))) {
231 if(pcb
->so_options
& SOF_REUSEPORT
) {
233 /* We processed one PCB already */
234 LWIP_DEBUGF(UDP_DEBUG
, ("udp_input: second or later PCB and SOF_REUSEPORT set.\n"));
236 /* First PCB with this address */
237 LWIP_DEBUGF(UDP_DEBUG
, ("udp_input: first PCB and SOF_REUSEPORT set.\n"));
243 LWIP_DEBUGF(UDP_DEBUG
, ("udp_input: reference counter on PBUF set to %i\n", p
->ref
));
246 /* We processed one PCB already */
247 LWIP_DEBUGF(UDP_DEBUG
, ("udp_input: second or later PCB but SOF_REUSEPORT not set !\n"));
250 #endif /* SO_REUSE */
254 /* no fully matching pcb found? then look for an unconnected pcb */
256 /* Iterate through the UDP PCB list for a pcb that matches
257 the local address. */
264 for(pcb
= pcb_temp
; pcb
!= NULL
; pcb
= pcb
->next
) {
266 for(pcb
= udp_pcbs
; pcb
!= NULL
; pcb
= pcb
->next
) {
267 #endif /* SO_REUSE */
268 LWIP_DEBUGF(UDP_DEBUG
, ("pcb (%u.%u.%u.%u, %u) --- (%u.%u.%u.%u, %u)\n",
269 ip4_addr1(&pcb
->local_ip
), ip4_addr2(&pcb
->local_ip
),
270 ip4_addr3(&pcb
->local_ip
), ip4_addr4(&pcb
->local_ip
), pcb
->local_port
,
271 ip4_addr1(&pcb
->remote_ip
), ip4_addr2(&pcb
->remote_ip
),
272 ip4_addr3(&pcb
->remote_ip
), ip4_addr4(&pcb
->remote_ip
), pcb
->remote_port
));
274 if (((pcb
->flags
& UDP_FLAGS_CONNECTED
) == 0) &&
275 /* destination port matches? */
276 (pcb
->local_port
== dest
) &&
277 /* not bound to a specific (local) interface address? or... */
278 (ip_addr_isany(&pcb
->local_ip
) ||
279 /* ...matching interface address? */
280 ip_addr_cmp(&(pcb
->local_ip
), &(iphdr
->dest
)))) {
282 if(pcb
->so_options
& SOF_REUSEPORT
) {
284 /* We processed one PCB already */
285 LWIP_DEBUGF(UDP_DEBUG
, ("udp_input: second or later PCB and SOF_REUSEPORT set.\n"));
287 /* First PCB with this address */
288 LWIP_DEBUGF(UDP_DEBUG
, ("udp_input: first PCB and SOF_REUSEPORT set.\n"));
294 LWIP_DEBUGF(UDP_DEBUG
, ("udp_input: reference counter on PBUF set to %i\n", p
->ref
));
297 /* We processed one PCB already */
298 LWIP_DEBUGF(UDP_DEBUG
, ("udp_input: second or later PCB but SOF_REUSEPORT not set !\n"));
301 #endif /* SO_REUSE */
307 /* Check checksum if this is a match or if it was directed at us. */
308 if (pcb
!= NULL
|| ip_addr_cmp(&inp
->ip_addr
, &iphdr
->dest
))
310 LWIP_DEBUGF(UDP_DEBUG
| DBG_TRACE
, ("udp_input: calculating checksum\n"));
311 pbuf_header(p
, UDP_HLEN
);
313 if (iphdr
->nexthdr
== IP_PROTO_UDPLITE
) {
315 if (IPH_PROTO(iphdr
) == IP_PROTO_UDPLITE
) {
317 /* Do the UDP Lite checksum */
318 if (inet_chksum_pseudo(p
, (struct ip_addr
*)&(iphdr
->src
),
319 (struct ip_addr
*)&(iphdr
->dest
),
320 IP_PROTO_UDPLITE
, ntohs(udphdr
->len
)) != 0) {
321 LWIP_DEBUGF(UDP_DEBUG
| 2, ("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
322 UDP_STATS_INC(udp
.chkerr
);
323 UDP_STATS_INC(udp
.drop
);
324 snmp_inc_udpinerrors();
329 if (udphdr
->chksum
!= 0) {
330 if (inet_chksum_pseudo(p
, (struct ip_addr
*)&(iphdr
->src
),
331 (struct ip_addr
*)&(iphdr
->dest
),
332 IP_PROTO_UDP
, p
->tot_len
) != 0) {
333 LWIP_DEBUGF(UDP_DEBUG
| 2, ("udp_input: UDP datagram discarded due to failing checksum\n"));
335 UDP_STATS_INC(udp
.chkerr
);
336 UDP_STATS_INC(udp
.drop
);
337 snmp_inc_udpinerrors();
343 pbuf_header(p
, -UDP_HLEN
);
345 snmp_inc_udpindatagrams();
346 pcb
->recv(pcb
->recv_arg
, pcb
, p
, &(iphdr
->src
), src
);
348 /* First socket should receive now */
349 if(reuse_port_1
|| reuse_port_2
) {
350 /* We want to search on next socket after receiving */
351 pcb_temp
= pcb
->next
;
354 /* We are searching connected sockets */
359 /* We are searching unconnected sockets */
365 #endif /* SO_REUSE */
369 LWIP_DEBUGF(UDP_DEBUG
, ("udp_input: freeing PBUF with reference counter set to %i\n", p
->ref
));
373 #endif /* SO_REUSE */
374 LWIP_DEBUGF(UDP_DEBUG
| DBG_TRACE
, ("udp_input: not for us.\n"));
376 /* No match was found, send ICMP destination port unreachable unless
377 destination address was broadcast/multicast. */
379 if (!ip_addr_isbroadcast(&iphdr
->dest
, &inp
->netmask
) &&
380 !ip_addr_ismulticast(&iphdr
->dest
)) {
382 /* adjust pbuf pointer */
384 icmp_dest_unreach(p
, ICMP_DUR_PORT
);
386 UDP_STATS_INC(udp
.proterr
);
387 UDP_STATS_INC(udp
.drop
);
388 snmp_inc_udpnoports();
399 * Send data using UDP.
401 * @param pcb UDP PCB used to send the data.
402 * @param pbuf chain of pbuf's to be sent.
404 * @return lwIP error code.
405 * - ERR_OK. Successful. No error occured.
406 * - ERR_MEM. Out of memory.
407 * - ERR_USE. The specified ipaddr and port are already bound to by
410 * @see udp_disconnect()
413 udp_send(struct udp_pcb
*pcb
, struct pbuf
*p
)
415 struct udp_hdr
*udphdr
;
417 struct ip_addr
*src_ip
;
419 struct pbuf
*q
; /* q will be sent down the stack */
421 LWIP_DEBUGF(UDP_DEBUG
| DBG_TRACE
| 3, ("udp_send\n"));
423 /* if the PCB is not yet bound to a port, bind it here */
424 if (pcb
->local_port
== 0) {
425 LWIP_DEBUGF(UDP_DEBUG
| DBG_TRACE
| 2, ("udp_send: not yet bound to a port, binding now\n"));
426 err
= udp_bind(pcb
, &pcb
->local_ip
, pcb
->local_port
);
428 LWIP_DEBUGF(UDP_DEBUG
| DBG_TRACE
| 2, ("udp_send: forced port bind failed\n"));
433 /* not enough space to add an UDP header to first pbuf in given p chain? */
434 if (pbuf_header(p
, UDP_HLEN
)) {
435 /* allocate header in new pbuf */
436 q
= pbuf_alloc(PBUF_IP
, UDP_HLEN
, PBUF_RAM
);
437 /* new header pbuf could not be allocated? */
439 LWIP_DEBUGF(UDP_DEBUG
| DBG_TRACE
| 2, ("udp_send: could not allocate header\n"));
442 /* chain header q in front of given pbuf p */
444 /* { first pbuf q points to header pbuf } */
445 LWIP_DEBUGF(UDP_DEBUG
, ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q
, (void *)p
));
446 /* adding a header within p succeeded */
448 /* first pbuf q equals given pbuf */
450 LWIP_DEBUGF(UDP_DEBUG
, ("udp_send: added header in given pbuf %p\n", (void *)p
));
452 /* { q now represents the packet to be sent */
454 udphdr
->src
= htons(pcb
->local_port
);
455 udphdr
->dest
= htons(pcb
->remote_port
);
456 udphdr
->chksum
= 0x0000;
458 if ((netif
= ip_route(&(pcb
->remote_ip
))) == NULL
) {
459 LWIP_DEBUGF(UDP_DEBUG
| 1, ("udp_send: No route to 0x%lx\n", pcb
->remote_ip
.addr
));
460 UDP_STATS_INC(udp
.rterr
);
463 /* using IP_ANY_ADDR? */
464 if (ip_addr_isany(&pcb
->local_ip
)) {
465 /* use outgoing network interface IP address as source address */
466 src_ip
= &(netif
->ip_addr
);
468 /* use UDP PCB local IP address as source address */
469 src_ip
= &(pcb
->local_ip
);
472 LWIP_DEBUGF(UDP_DEBUG
, ("udp_send: sending datagram of length %u\n", q
->tot_len
));
474 /* UDP Lite protocol? */
475 if (pcb
->flags
& UDP_FLAGS_UDPLITE
) {
476 LWIP_DEBUGF(UDP_DEBUG
, ("udp_send: UDP LITE packet length %u\n", q
->tot_len
));
477 /* set UDP message length in UDP header */
478 udphdr
->len
= htons(pcb
->chksum_len
);
479 /* calculate checksum */
480 udphdr
->chksum
= inet_chksum_pseudo(q
, src_ip
, &(pcb
->remote_ip
),
481 IP_PROTO_UDP
, pcb
->chksum_len
);
482 /* chksum zero must become 0xffff, as zero means 'no checksum' */
483 if (udphdr
->chksum
== 0x0000) udphdr
->chksum
= 0xffff;
485 err
= ip_output_if (q
, src_ip
, &pcb
->remote_ip
, pcb
->ttl
, pcb
->tos
, IP_PROTO_UDPLITE
, netif
);
486 snmp_inc_udpoutdatagrams();
488 LWIP_DEBUGF(UDP_DEBUG
, ("udp_send: UDP packet length %u\n", q
->tot_len
));
489 udphdr
->len
= htons(q
->tot_len
);
490 /* calculate checksum */
491 if ((pcb
->flags
& UDP_FLAGS_NOCHKSUM
) == 0) {
492 udphdr
->chksum
= inet_chksum_pseudo(q
, src_ip
, &pcb
->remote_ip
, IP_PROTO_UDP
, q
->tot_len
);
493 /* chksum zero must become 0xffff, as zero means 'no checksum' */
494 if (udphdr
->chksum
== 0x0000) udphdr
->chksum
= 0xffff;
496 LWIP_DEBUGF(UDP_DEBUG
, ("udp_send: UDP checksum 0x%04x\n", udphdr
->chksum
));
497 snmp_inc_udpoutdatagrams();
498 LWIP_DEBUGF(UDP_DEBUG
, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
500 err
= ip_output_if(q
, src_ip
, &pcb
->remote_ip
, pcb
->ttl
, pcb
->tos
, IP_PROTO_UDP
, netif
);
503 /* did we chain a header earlier? */
505 /* free the header */
506 /* p is also still referenced by the caller, and will live on */
510 UDP_STATS_INC(udp
.xmit
);
517 * @param pcb UDP PCB to be bound with a local address ipaddr and port.
518 * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to
519 * bind to all local interfaces.
520 * @param port local UDP port to bind with.
522 * @return lwIP error code.
523 * - ERR_OK. Successful. No error occured.
524 * - ERR_USE. The specified ipaddr and port are already bound to by
527 * @see udp_disconnect()
530 udp_bind(struct udp_pcb
*pcb
, struct ip_addr
*ipaddr
, u16_t port
)
532 struct udp_pcb
*ipcb
;
535 int reuse_port_all_set
= 1;
536 #endif /* SO_REUSE */
537 LWIP_DEBUGF(UDP_DEBUG
| DBG_TRACE
| 3, ("udp_bind(ipaddr = "));
538 ip_addr_debug_print(UDP_DEBUG
, ipaddr
);
539 LWIP_DEBUGF(UDP_DEBUG
| DBG_TRACE
| 3, (", port = %u)\n", port
));
542 /* Check for double bind and rebind of the same pcb */
543 for (ipcb
= udp_pcbs
; ipcb
!= NULL
; ipcb
= ipcb
->next
) {
544 /* is this UDP PCB already on active list? */
546 /* pcb may occur at most once in active list */
547 LWIP_ASSERT("rebind == 0", rebind
== 0);
548 /* pcb already in list, just rebind */
553 /* this code does not allow upper layer to share a UDP port for
554 listening to broadcast or multicast traffic (See SO_REUSE_ADDR and
555 SO_REUSE_PORT under *BSD). TODO: See where it fits instead, OR
556 combine with implementation of UDP PCB flags. Leon Woestenberg. */
558 /* port matches that of PCB in list? */
559 else if ((ipcb
->local_port
== port
) &&
560 /* IP address matches, or one is IP_ADDR_ANY? */
561 (ip_addr_isany(&(ipcb
->local_ip
)) ||
562 ip_addr_isany(ipaddr
) ||
563 ip_addr_cmp(&(ipcb
->local_ip
), ipaddr
))) {
564 /* other PCB already binds to this local IP and port */
565 LWIP_DEBUGF(UDP_DEBUG
, ("udp_bind: local port %u already bound by another pcb\n", port
));
571 /* Search through list of PCB's.
573 If there is a PCB bound to specified port and IP_ADDR_ANY another PCB can be bound to the interface IP
574 or to the loopback address on the same port if SOF_REUSEADDR is set. Any combination of PCB's bound to
575 the same local port, but to one address out of {IP_ADDR_ANY, 127.0.0.1, interface IP} at a time is valid.
576 But no two PCB's bound to same local port and same local address is valid.
578 If SOF_REUSEPORT is set several PCB's can be bound to same local port and same local address also. But then
579 all PCB's must have the SOF_REUSEPORT option set.
581 When the two options aren't set and specified port is already bound, ERR_USE is returned saying that
582 address is already in use. */
583 else if (ipcb
->local_port
== port
) {
584 if(ip_addr_cmp(&(ipcb
->local_ip
), ipaddr
)) {
585 if(pcb
->so_options
& SOF_REUSEPORT
) {
586 LWIP_DEBUGF(UDP_DEBUG
, ("udp_bind: in UDP PCB's SO_REUSEPORT set and same address.\n"));
587 reuse_port_all_set
= (reuse_port_all_set
&& (ipcb
->so_options
& SOF_REUSEPORT
));
590 LWIP_DEBUGF(UDP_DEBUG
, ("udp_bind: in UDP PCB's SO_REUSEPORT not set and same address.\n"));
594 else if((ip_addr_isany(ipaddr
) && !ip_addr_isany(&(ipcb
->local_ip
))) ||
595 (!ip_addr_isany(ipaddr
) && ip_addr_isany(&(ipcb
->local_ip
)))) {
596 if(!(pcb
->so_options
& SOF_REUSEADDR
) && !(pcb
->so_options
& SOF_REUSEPORT
)) {
597 LWIP_DEBUGF(UDP_DEBUG
, ("udp_bind: in UDP PCB's SO_REUSEPORT or SO_REUSEADDR not set and not the same address.\n"));
602 #endif /* SO_REUSE */
607 /* If SOF_REUSEPORT isn't set in all PCB's bound to specified port and local address specified then
608 {IP, port} can't be reused. */
609 if(!reuse_port_all_set
) {
610 LWIP_DEBUGF(UDP_DEBUG
, ("udp_bind: not all sockets have SO_REUSEPORT set.\n"));
613 #endif /* SO_REUSE */
615 ip_addr_set(&pcb
->local_ip
, ipaddr
);
616 /* no port specified? */
618 #ifndef UDP_LOCAL_PORT_RANGE_START
619 #define UDP_LOCAL_PORT_RANGE_START 4096
620 #define UDP_LOCAL_PORT_RANGE_END 0x7fff
622 port
= UDP_LOCAL_PORT_RANGE_START
;
624 while ((ipcb
!= NULL
) && (port
!= UDP_LOCAL_PORT_RANGE_END
)) {
625 if (ipcb
->local_port
== port
) {
632 /* no more ports available in local range */
633 LWIP_DEBUGF(UDP_DEBUG
, ("udp_bind: out of free UDP ports\n"));
637 pcb
->local_port
= port
;
638 /* pcb not active yet? */
640 /* place the PCB on the active list if not already there */
641 pcb
->next
= udp_pcbs
;
644 LWIP_DEBUGF(UDP_DEBUG
| DBG_TRACE
| DBG_STATE
, ("udp_bind: bound to %u.%u.%u.%u, port %u\n",
645 (unsigned int)(ntohl(pcb
->local_ip
.addr
) >> 24 & 0xff),
646 (unsigned int)(ntohl(pcb
->local_ip
.addr
) >> 16 & 0xff),
647 (unsigned int)(ntohl(pcb
->local_ip
.addr
) >> 8 & 0xff),
648 (unsigned int)(ntohl(pcb
->local_ip
.addr
) & 0xff), pcb
->local_port
));
652 * Connect an UDP PCB.
654 * This will associate the UDP PCB with the remote address.
656 * @param pcb UDP PCB to be connected with remote address ipaddr and port.
657 * @param ipaddr remote IP address to connect with.
658 * @param port remote UDP port to connect with.
660 * @return lwIP error code
662 * @see udp_disconnect()
665 udp_connect(struct udp_pcb
*pcb
, struct ip_addr
*ipaddr
, u16_t port
)
667 struct udp_pcb
*ipcb
;
669 if (pcb
->local_port
== 0) {
670 err_t err
= udp_bind(pcb
, &pcb
->local_ip
, pcb
->local_port
);
675 ip_addr_set(&pcb
->remote_ip
, ipaddr
);
676 pcb
->remote_port
= port
;
677 pcb
->flags
|= UDP_FLAGS_CONNECTED
;
678 /** TODO: this functionality belongs in upper layers */
680 /* Nail down local IP for netconn_addr()/getsockname() */
681 if (ip_addr_isany(&pcb
->local_ip
) && !ip_addr_isany(&pcb
->remote_ip
)) {
684 if ((netif
= ip_route(&(pcb
->remote_ip
))) == NULL
) {
685 LWIP_DEBUGF(UDP_DEBUG
, ("udp_connect: No route to 0x%lx\n", pcb
->remote_ip
.addr
));
686 UDP_STATS_INC(udp
.rterr
);
689 /** TODO: this will bind the udp pcb locally, to the interface which
690 is used to route output packets to the remote address. However, we
691 might want to accept incoming packets on any interface! */
692 pcb
->local_ip
= netif
->ip_addr
;
693 } else if (ip_addr_isany(&pcb
->remote_ip
)) {
694 pcb
->local_ip
.addr
= 0;
697 LWIP_DEBUGF(UDP_DEBUG
| DBG_TRACE
| DBG_STATE
, ("udp_connect: connected to %u.%u.%u.%u, port %u\n",
698 (unsigned int)(ntohl(pcb
->remote_ip
.addr
) >> 24 & 0xff),
699 (unsigned int)(ntohl(pcb
->remote_ip
.addr
) >> 16 & 0xff),
700 (unsigned int)(ntohl(pcb
->remote_ip
.addr
) >> 8 & 0xff),
701 (unsigned int)(ntohl(pcb
->remote_ip
.addr
) & 0xff), pcb
->remote_port
));
703 /* Insert UDP PCB into the list of active UDP PCBs. */
704 for(ipcb
= udp_pcbs
; ipcb
!= NULL
; ipcb
= ipcb
->next
) {
706 /* already on the list, just return */
710 /* PCB not yet on the list, add PCB now */
711 pcb
->next
= udp_pcbs
;
717 udp_disconnect(struct udp_pcb
*pcb
)
719 pcb
->flags
&= ~UDP_FLAGS_CONNECTED
;
723 udp_recv(struct udp_pcb
*pcb
,
724 void (* recv
)(void *arg
, struct udp_pcb
*upcb
, struct pbuf
*p
,
725 struct ip_addr
*addr
, u16_t port
),
728 /* remember recv() callback and user data */
730 pcb
->recv_arg
= recv_arg
;
735 * @param pcb UDP PCB to be removed. The PCB is removed from the list of
736 * UDP PCB's and the data structure is freed from memory.
741 udp_remove(struct udp_pcb
*pcb
)
743 struct udp_pcb
*pcb2
;
744 /* pcb to be removed is first in list? */
745 if (udp_pcbs
== pcb
) {
746 /* make list start at 2nd pcb */
747 udp_pcbs
= udp_pcbs
->next
;
748 /* pcb not 1st in list */
749 } else for(pcb2
= udp_pcbs
; pcb2
!= NULL
; pcb2
= pcb2
->next
) {
750 /* find pcb in udp_pcbs list */
751 if (pcb2
->next
!= NULL
&& pcb2
->next
== pcb
) {
752 /* remove pcb from list */
753 pcb2
->next
= pcb
->next
;
756 memp_free(MEMP_UDP_PCB
, pcb
);
761 * @return The UDP PCB which was created. NULL if the PCB data structure
762 * could not be allocated.
769 pcb
= memp_malloc(MEMP_UDP_PCB
);
770 /* could allocate UDP PCB? */
772 /* initialize PCB to all zeroes */
773 mips_memset(pcb
, 0, sizeof(struct udp_pcb
));
783 udp_debug_print(struct udp_hdr
*udphdr
)
785 LWIP_DEBUGF(UDP_DEBUG
, ("UDP header:\n"));
786 LWIP_DEBUGF(UDP_DEBUG
, ("+-------------------------------+\n"));
787 LWIP_DEBUGF(UDP_DEBUG
, ("| %5u | %5u | (src port, dest port)\n",
788 ntohs(udphdr
->src
), ntohs(udphdr
->dest
)));
789 LWIP_DEBUGF(UDP_DEBUG
, ("+-------------------------------+\n"));
790 LWIP_DEBUGF(UDP_DEBUG
, ("| %5u | 0x%04x | (len, chksum)\n",
791 ntohs(udphdr
->len
), ntohs(udphdr
->chksum
)));
792 LWIP_DEBUGF(UDP_DEBUG
, ("+-------------------------------+\n"));
795 #endif /* UDP_DEBUG */
797 #endif /* LWIP_UDP */