]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lwip.git/blob - src/core/udp.c
udp_input: fixed unreachable code warning for CHECKSUM_CHECK_UDP==0
[pes-rpp/rpp-lwip.git] / src / core / udp.c
1 /**
2  * @file
3  * User Datagram Protocol module
4  *
5  */
6
7 /*
8  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without modification,
12  * are permitted provided that the following conditions are met:
13  *
14  * 1. Redistributions of source code must retain the above copyright notice,
15  *    this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright notice,
17  *    this list of conditions and the following disclaimer in the documentation
18  *    and/or other materials provided with the distribution.
19  * 3. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
23  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
27  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
31  * OF SUCH DAMAGE.
32  *
33  * This file is part of the lwIP TCP/IP stack.
34  *
35  * Author: Adam Dunkels <adam@sics.se>
36  *
37  */
38
39
40 /* udp.c
41  *
42  * The code for the User Datagram Protocol UDP & UDPLite (RFC 3828).
43  *
44  */
45
46 /* @todo Check the use of '(struct udp_pcb).chksum_len_rx'!
47  */
48
49 #include "lwip/opt.h"
50
51 #if LWIP_UDP /* don't build if not configured for use in lwipopts.h */
52
53 #include "lwip/udp.h"
54 #include "lwip/def.h"
55 #include "lwip/memp.h"
56 #include "lwip/inet_chksum.h"
57 #include "lwip/ip_addr.h"
58 #include "lwip/ip6.h"
59 #include "lwip/ip6_addr.h"
60 #include "lwip/inet_chksum.h"
61 #include "lwip/netif.h"
62 #include "lwip/icmp.h"
63 #include "lwip/icmp6.h"
64 #include "lwip/stats.h"
65 #include "lwip/snmp.h"
66 #include "arch/perf.h"
67 #include "lwip/dhcp.h"
68
69 #include <string.h>
70
71 #ifndef UDP_LOCAL_PORT_RANGE_START
72 /* From http://www.iana.org/assignments/port-numbers:
73    "The Dynamic and/or Private Ports are those from 49152 through 65535" */
74 #define UDP_LOCAL_PORT_RANGE_START  0xc000
75 #define UDP_LOCAL_PORT_RANGE_END    0xffff
76 #define UDP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~UDP_LOCAL_PORT_RANGE_START) + UDP_LOCAL_PORT_RANGE_START)
77 #endif
78
79 /* last local UDP port */
80 static u16_t udp_port = UDP_LOCAL_PORT_RANGE_START;
81
82 /* The list of UDP PCBs */
83 /* exported in udp.h (was static) */
84 struct udp_pcb *udp_pcbs;
85
86 /**
87  * Initialize this module.
88  */
89 void
90 udp_init(void)
91 {
92 #if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND)
93   udp_port = UDP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND());
94 #endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */
95 }
96
97 /**
98  * Allocate a new local UDP port.
99  *
100  * @return a new (free) local UDP port number
101  */
102 static u16_t
103 udp_new_port(void)
104 {
105   u16_t n = 0;
106   struct udp_pcb *pcb;
107   
108 again:
109   if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) {
110     udp_port = UDP_LOCAL_PORT_RANGE_START;
111   }
112   /* Check all PCBs. */
113   for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
114     if (pcb->local_port == udp_port) {
115       if (++n > (UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START)) {
116         return 0;
117       }
118       goto again;
119     }
120   }
121   return udp_port;
122 #if 0
123   struct udp_pcb *ipcb = udp_pcbs;
124   while ((ipcb != NULL) && (udp_port != UDP_LOCAL_PORT_RANGE_END)) {
125     if (ipcb->local_port == udp_port) {
126       /* port is already used by another udp_pcb */
127       udp_port++;
128       /* restart scanning all udp pcbs */
129       ipcb = udp_pcbs;
130     } else {
131       /* go on with next udp pcb */
132       ipcb = ipcb->next;
133     }
134   }
135   if (ipcb != NULL) {
136     return 0;
137   }
138   return udp_port;
139 #endif
140 }
141
142 /**
143  * Process an incoming UDP datagram.
144  *
145  * Given an incoming UDP datagram (as a chain of pbufs) this function
146  * finds a corresponding UDP PCB and hands over the pbuf to the pcbs
147  * recv function. If no pcb is found or the datagram is incorrect, the
148  * pbuf is freed.
149  *
150  * @param p pbuf to be demultiplexed to a UDP PCB (p->payload pointing to the UDP header)
151  * @param inp network interface on which the datagram was received.
152  *
153  */
154 void
155 udp_input(struct pbuf *p, struct netif *inp)
156 {
157   struct udp_hdr *udphdr;
158   struct udp_pcb *pcb, *prev;
159   struct udp_pcb *uncon_pcb;
160   u16_t src, dest;
161   u8_t local_match;
162   u8_t broadcast;
163   u8_t for_us;
164
165   PERF_START;
166
167   UDP_STATS_INC(udp.recv);
168
169   /* Check minimum length (UDP header) */
170   if (p->len < UDP_HLEN) {
171     /* drop short packets */
172     LWIP_DEBUGF(UDP_DEBUG,
173                 ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len));
174     UDP_STATS_INC(udp.lenerr);
175     UDP_STATS_INC(udp.drop);
176     snmp_inc_udpinerrors();
177     pbuf_free(p);
178     goto end;
179   }
180
181   udphdr = (struct udp_hdr *)p->payload;
182
183   /* is broadcast packet ? */
184 #if LWIP_IPV6
185   broadcast = !ip_current_is_v6() && ip_addr_isbroadcast(ip_current_dest_addr(), inp);
186 #else /* LWIP_IPV6 */
187   broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), inp);
188 #endif /* LWIP_IPV6 */
189
190   LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len));
191
192   /* convert src and dest ports to host byte order */
193   src = ntohs(udphdr->src);
194   dest = ntohs(udphdr->dest);
195
196   udp_debug_print(udphdr);
197
198   /* print the UDP source and destination */
199   LWIP_DEBUGF(UDP_DEBUG, ("udp ("));
200   ipX_addr_debug_print(ip_current_is_v6(), UDP_DEBUG, ipX_current_dest_addr());
201   LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", ntohs(udphdr->dest)));
202   ipX_addr_debug_print(ip_current_is_v6(), UDP_DEBUG, ipX_current_src_addr());
203   LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", ntohs(udphdr->src)));
204
205 #if LWIP_DHCP
206   pcb = NULL;
207   /* when LWIP_DHCP is active, packets to DHCP_CLIENT_PORT may only be processed by
208      the dhcp module, no other UDP pcb may use the local UDP port DHCP_CLIENT_PORT */
209   if (dest == DHCP_CLIENT_PORT) {
210     /* all packets for DHCP_CLIENT_PORT not coming from DHCP_SERVER_PORT are dropped! */
211     if (src == DHCP_SERVER_PORT) {
212       if ((inp->dhcp != NULL) && (inp->dhcp->pcb != NULL)) {
213         /* accept the packe if 
214            (- broadcast or directed to us) -> DHCP is link-layer-addressed, local ip is always ANY!
215            - inp->dhcp->pcb->remote == ANY or iphdr->src
216            (no need to check for IPv6 since the dhcp struct always uses IPv4) */
217         if (ipX_addr_isany(0, &inp->dhcp->pcb->remote_ip) ||
218             ip_addr_cmp(ipX_2_ip(&(inp->dhcp->pcb->remote_ip)), ip_current_src_addr())) {
219           pcb = inp->dhcp->pcb;
220         }
221       }
222     }
223   } else
224 #endif /* LWIP_DHCP */
225   {
226     prev = NULL;
227     local_match = 0;
228     uncon_pcb = NULL;
229     /* Iterate through the UDP pcb list for a matching pcb.
230      * 'Perfect match' pcbs (connected to the remote port & ip address) are
231      * preferred. If no perfect match is found, the first unconnected pcb that
232      * matches the local port and ip address gets the datagram. */
233     for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
234       local_match = 0;
235       /* print the PCB local and remote address */
236       LWIP_DEBUGF(UDP_DEBUG, ("pcb ("));
237       ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG, &pcb->local_ip);
238       LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", pcb->local_port));
239       ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG, &pcb->remote_ip);
240       LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", pcb->remote_port));
241
242       /* compare PCB local addr+port to UDP destination addr+port */
243       if (pcb->local_port == dest) {
244         if (
245 #if LWIP_IPV6
246           ((PCB_ISIPV6(pcb) && (ip_current_is_v6()) &&
247             (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip)) ||
248 #if LWIP_IPV6_MLD
249             ip6_addr_ismulticast(ip6_current_dest_addr()) ||
250 #endif /* LWIP_IPV6_MLD */
251             ip6_addr_cmp(ipX_2_ip6(&pcb->local_ip), ip6_current_dest_addr()))) ||
252            (!PCB_ISIPV6(pcb) &&
253             (ip_current_header() != NULL) &&
254 #else /* LWIP_IPV6 */
255            ((
256 #endif /* LWIP_IPV6 */
257             ((!broadcast && ipX_addr_isany(0, &pcb->local_ip)) ||
258             ip_addr_cmp(ipX_2_ip(&pcb->local_ip), ip_current_dest_addr()) ||
259 #if LWIP_IGMP
260             ip_addr_ismulticast(ip_current_dest_addr()) ||
261 #endif /* LWIP_IGMP */
262 #if IP_SOF_BROADCAST_RECV
263             (broadcast && ip_get_option(pcb, SOF_BROADCAST) &&
264              (ipX_addr_isany(0, &pcb->local_ip) ||
265               ip_addr_netcmp(ipX_2_ip(&pcb->local_ip), ip_current_dest_addr(), &inp->netmask))))))) {
266 #else /* IP_SOF_BROADCAST_RECV */
267             (broadcast &&
268              (ipX_addr_isany(0, &pcb->local_ip) ||
269               ip_addr_netcmp(ipX_2_ip(&pcb->local_ip), ip_current_dest_addr(), &inp->netmask))))))) {
270 #endif /* IP_SOF_BROADCAST_RECV */ 
271           local_match = 1;
272           if ((uncon_pcb == NULL) && 
273               ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) {
274             /* the first unconnected matching PCB */
275             uncon_pcb = pcb;
276           }
277         }
278       }
279       /* compare PCB remote addr+port to UDP source addr+port */
280       if ((local_match != 0) &&
281           (pcb->remote_port == src) && IP_PCB_IPVER_INPUT_MATCH(pcb) &&
282             (ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->remote_ip) ||
283               ipX_addr_cmp(PCB_ISIPV6(pcb), &pcb->remote_ip, ipX_current_src_addr()))) {
284         /* the first fully matching PCB */
285         if (prev != NULL) {
286           /* move the pcb to the front of udp_pcbs so that is
287              found faster next time */
288           prev->next = pcb->next;
289           pcb->next = udp_pcbs;
290           udp_pcbs = pcb;
291         } else {
292           UDP_STATS_INC(udp.cachehit);
293         }
294         break;
295       }
296       prev = pcb;
297     }
298     /* no fully matching pcb found? then look for an unconnected pcb */
299     if (pcb == NULL) {
300       pcb = uncon_pcb;
301     }
302   }
303
304   /* Check checksum if this is a match or if it was directed at us. */
305   if (pcb != NULL) {
306     for_us = 1;
307   } else {
308 #if LWIP_IPV6
309     if (ip_current_is_v6()) {
310       for_us = netif_matches_ip6_addr(inp, ip6_current_dest_addr());
311     } else
312 #endif /* LWIP_IPV6 */
313     {
314       for_us = ip_addr_cmp(&inp->ip_addr, ip_current_dest_addr());
315     }
316   }
317   if (for_us) {
318     LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n"));
319 #if CHECKSUM_CHECK_UDP
320 #if LWIP_UDPLITE
321     if (ip_current_header_proto() == IP_PROTO_UDPLITE) {
322       /* Do the UDP Lite checksum */
323       u16_t chklen = ntohs(udphdr->len);
324       if (chklen < sizeof(struct udp_hdr)) {
325         if (chklen == 0) {
326           /* For UDP-Lite, checksum length of 0 means checksum
327              over the complete packet (See RFC 3828 chap. 3.1) */
328           chklen = p->tot_len;
329         } else {
330           /* At least the UDP-Lite header must be covered by the
331              checksum! (Again, see RFC 3828 chap. 3.1) */
332           goto chkerr;
333         }
334       }
335       if (ipX_chksum_pseudo_partial(ip_current_is_v6(), p, IP_PROTO_UDPLITE,
336                    p->tot_len, chklen,
337                    ipX_current_src_addr(), ipX_current_dest_addr()) != 0) {
338         goto chkerr;
339       }
340     } else
341 #endif /* LWIP_UDPLITE */
342     {
343       if (udphdr->chksum != 0) {
344         if (ipX_chksum_pseudo(ip_current_is_v6(), p, IP_PROTO_UDP, p->tot_len,
345                               ipX_current_src_addr(),
346                               ipX_current_dest_addr()) != 0) {
347           goto chkerr;
348         }
349       }
350     }
351 #endif /* CHECKSUM_CHECK_UDP */
352     if(pbuf_header(p, -UDP_HLEN)) {
353       /* Can we cope with this failing? Just assert for now */
354       LWIP_ASSERT("pbuf_header failed\n", 0);
355       UDP_STATS_INC(udp.drop);
356       snmp_inc_udpinerrors();
357       pbuf_free(p);
358       goto end;
359     }
360     if (pcb != NULL) {
361       snmp_inc_udpindatagrams();
362 #if SO_REUSE && SO_REUSE_RXTOALL
363       if ((broadcast ||
364 #if LWIP_IPV6
365           ip6_addr_ismulticast(ip6_current_dest_addr()) ||
366 #endif /* LWIP_IPV6 */
367            ip_addr_ismulticast(ip_current_dest_addr())) &&
368           ip_get_option(pcb, SOF_REUSEADDR)) {
369         /* pass broadcast- or multicast packets to all multicast pcbs
370            if SOF_REUSEADDR is set on the first match */
371         struct udp_pcb *mpcb;
372         u8_t p_header_changed = 0;
373         s16_t hdrs_len = (s16_t)(ip_current_header_tot_len() + UDP_HLEN);
374         for (mpcb = udp_pcbs; mpcb != NULL; mpcb = mpcb->next) {
375           if (mpcb != pcb) {
376             /* compare PCB local addr+port to UDP destination addr+port */
377             if ((mpcb->local_port == dest) &&
378 #if LWIP_IPV6
379                 ((PCB_ISIPV6(mpcb) &&
380                   (ip6_addr_ismulticast(ip6_current_dest_addr()) ||
381                    ip6_addr_cmp(ipX_2_ip6(&mpcb->local_ip), ip6_current_dest_addr()))) ||
382                  (!PCB_ISIPV6(mpcb) &&
383 #else /* LWIP_IPV6 */
384                 ((
385 #endif /* LWIP_IPV6 */
386                   ((!broadcast && ipX_addr_isany(0, &mpcb->local_ip)) ||
387                    ip_addr_cmp(ipX_2_ip(&mpcb->local_ip), ip_current_dest_addr()) ||
388 #if LWIP_IGMP
389                    ip_addr_ismulticast(ip_current_dest_addr()) ||
390 #endif /* LWIP_IGMP */
391 #if IP_SOF_BROADCAST_RECV
392                    (broadcast && ip_get_option(mpcb, SOF_BROADCAST)))))) {
393 #else  /* IP_SOF_BROADCAST_RECV */
394                    (broadcast))))) {
395 #endif /* IP_SOF_BROADCAST_RECV */
396               /* pass a copy of the packet to all local matches */
397               if (mpcb->recv.ip4 != NULL) {
398                 struct pbuf *q;
399                 /* for that, move payload to IP header again */
400                 if (p_header_changed == 0) {
401                   pbuf_header(p, hdrs_len);
402                   p_header_changed = 1;
403                 }
404                 q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
405                 if (q != NULL) {
406                   err_t err = pbuf_copy(q, p);
407                   if (err == ERR_OK) {
408                     /* move payload to UDP data */
409                     pbuf_header(q, -hdrs_len);
410 #if LWIP_IPV6
411                     if (PCB_ISIPV6(mpcb)) {
412                       mpcb->recv.ip6(mpcb->recv_arg, mpcb, q, ip6_current_src_addr(), src);
413                     }
414                     else
415 #endif /* LWIP_IPV6 */
416                     {
417                       mpcb->recv.ip4(mpcb->recv_arg, mpcb, q, ip_current_src_addr(), src);
418                     }
419                   }
420                 }
421               }
422             }
423           }
424         }
425         if (p_header_changed) {
426           /* and move payload to UDP data again */
427           pbuf_header(p, -hdrs_len);
428         }
429       }
430 #endif /* SO_REUSE && SO_REUSE_RXTOALL */
431       /* callback */
432       if (pcb->recv.ip4 != NULL) {
433         /* now the recv function is responsible for freeing p */
434 #if LWIP_IPV6
435         if (PCB_ISIPV6(pcb)) {
436           pcb->recv.ip6(pcb->recv_arg, pcb, p, ip6_current_src_addr(), src);
437         }
438         else
439 #endif /* LWIP_IPV6 */
440         {
441           pcb->recv.ip4(pcb->recv_arg, pcb, p, ip_current_src_addr(), src);
442         }
443       } else {
444         /* no recv function registered? then we have to free the pbuf! */
445         pbuf_free(p);
446         goto end;
447       }
448     } else {
449       LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: not for us.\n"));
450
451 #if LWIP_ICMP || LWIP_ICMP6
452       /* No match was found, send ICMP destination port unreachable unless
453          destination address was broadcast/multicast. */
454       if (!broadcast &&
455 #if LWIP_IPV6
456           !ip6_addr_ismulticast(ip6_current_dest_addr()) &&
457 #endif /* LWIP_IPV6 */
458           !ip_addr_ismulticast(ip_current_dest_addr())) {
459         /* move payload pointer back to ip header */
460         pbuf_header(p, ip_current_header_tot_len() + UDP_HLEN);
461         icmp_port_unreach(ip_current_is_v6(), p);
462       }
463 #endif /* LWIP_ICMP || LWIP_ICMP6 */
464       UDP_STATS_INC(udp.proterr);
465       UDP_STATS_INC(udp.drop);
466       snmp_inc_udpnoports();
467       pbuf_free(p);
468     }
469   } else {
470     pbuf_free(p);
471   }
472 end:
473   PERF_STOP("udp_input");
474   return;
475 #if CHECKSUM_CHECK_UDP
476 chkerr:
477   LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
478               ("udp_input: UDP (or UDP Lite) datagram discarded due to failing checksum\n"));
479   UDP_STATS_INC(udp.chkerr);
480   UDP_STATS_INC(udp.drop);
481   snmp_inc_udpinerrors();
482   pbuf_free(p);
483   PERF_STOP("udp_input");
484 #endif /* CHECKSUM_CHECK_UDP */
485 }
486
487 /**
488  * Send data using UDP.
489  *
490  * @param pcb UDP PCB used to send the data.
491  * @param p chain of pbuf's to be sent.
492  *
493  * The datagram will be sent to the current remote_ip & remote_port
494  * stored in pcb. If the pcb is not bound to a port, it will
495  * automatically be bound to a random port.
496  *
497  * @return lwIP error code.
498  * - ERR_OK. Successful. No error occured.
499  * - ERR_MEM. Out of memory.
500  * - ERR_RTE. Could not find route to destination address.
501  * - More errors could be returned by lower protocol layers.
502  *
503  * @see udp_disconnect() udp_sendto()
504  */
505 err_t
506 udp_send(struct udp_pcb *pcb, struct pbuf *p)
507 {
508   /* send to the packet using remote ip and port stored in the pcb */
509   return udp_sendto(pcb, p, ipX_2_ip(&pcb->remote_ip), pcb->remote_port);
510 }
511
512 #if LWIP_CHECKSUM_ON_COPY
513 /** Same as udp_send() but with checksum
514  */
515 err_t
516 udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p,
517                 u8_t have_chksum, u16_t chksum)
518 {
519   /* send to the packet using remote ip and port stored in the pcb */
520   return udp_sendto_chksum(pcb, p, ipX_2_ip(&pcb->remote_ip), pcb->remote_port,
521     have_chksum, chksum);
522 }
523 #endif /* LWIP_CHECKSUM_ON_COPY */
524
525 /**
526  * Send data to a specified address using UDP.
527  *
528  * @param pcb UDP PCB used to send the data.
529  * @param p chain of pbuf's to be sent.
530  * @param dst_ip Destination IP address.
531  * @param dst_port Destination UDP port.
532  *
533  * dst_ip & dst_port are expected to be in the same byte order as in the pcb.
534  *
535  * If the PCB already has a remote address association, it will
536  * be restored after the data is sent.
537  * 
538  * @return lwIP error code (@see udp_send for possible error codes)
539  *
540  * @see udp_disconnect() udp_send()
541  */
542 err_t
543 udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
544   ip_addr_t *dst_ip, u16_t dst_port)
545 {
546 #if LWIP_CHECKSUM_ON_COPY
547   return udp_sendto_chksum(pcb, p, dst_ip, dst_port, 0, 0);
548 }
549
550 /** Same as udp_sendto(), but with checksum */
551 err_t
552 udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
553                   u16_t dst_port, u8_t have_chksum, u16_t chksum)
554 {
555 #endif /* LWIP_CHECKSUM_ON_COPY */
556   struct netif *netif;
557   ipX_addr_t *dst_ip_route = ip_2_ipX(dst_ip);
558
559   LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n"));
560
561 #if LWIP_IPV6 || LWIP_IGMP
562   if (ipX_addr_ismulticast(PCB_ISIPV6(pcb), dst_ip_route)) {
563     /* For multicast, find a netif based on source address. */
564 #if LWIP_IPV6
565     if (PCB_ISIPV6(pcb)) {
566       dst_ip_route = &pcb->local_ip;
567     } else
568 #endif /* LWIP_IPV6 */
569     {
570 #if LWIP_IGMP
571       dst_ip_route = ip_2_ipX(&pcb->multicast_ip);
572 #endif /* LWIP_IGMP */
573     }
574   }
575 #endif /* LWIP_IPV6 || LWIP_IGMP */
576
577   /* find the outgoing network interface for this packet */
578   netif = ipX_route(PCB_ISIPV6(pcb), &pcb->local_ip, dst_ip_route);
579
580   /* no outgoing network interface could be found? */
581   if (netif == NULL) {
582     LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to "));
583     ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ip_2_ipX(dst_ip));
584     LWIP_DEBUGF(UDP_DEBUG, ("\n"));
585     UDP_STATS_INC(udp.rterr);
586     return ERR_RTE;
587   }
588 #if LWIP_CHECKSUM_ON_COPY
589   return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum);
590 #else /* LWIP_CHECKSUM_ON_COPY */
591   return udp_sendto_if(pcb, p, dst_ip, dst_port, netif);
592 #endif /* LWIP_CHECKSUM_ON_COPY */
593 }
594
595 /**
596  * Send data to a specified address using UDP.
597  * The netif used for sending can be specified.
598  *
599  * This function exists mainly for DHCP, to be able to send UDP packets
600  * on a netif that is still down.
601  *
602  * @param pcb UDP PCB used to send the data.
603  * @param p chain of pbuf's to be sent.
604  * @param dst_ip Destination IP address.
605  * @param dst_port Destination UDP port.
606  * @param netif the netif used for sending.
607  *
608  * dst_ip & dst_port are expected to be in the same byte order as in the pcb.
609  *
610  * @return lwIP error code (@see udp_send for possible error codes)
611  *
612  * @see udp_disconnect() udp_send()
613  */
614 err_t
615 udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p,
616   ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif)
617 {
618 #if LWIP_CHECKSUM_ON_COPY
619   return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, 0, 0);
620 }
621
622 /** Same as udp_sendto_if(), but with checksum */
623 err_t
624 udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
625                      u16_t dst_port, struct netif *netif, u8_t have_chksum,
626                      u16_t chksum)
627 {
628 #endif /* LWIP_CHECKSUM_ON_COPY */
629   struct udp_hdr *udphdr;
630   ip_addr_t *src_ip;
631   err_t err;
632   struct pbuf *q; /* q will be sent down the stack */
633   u8_t ip_proto;
634
635 #if IP_SOF_BROADCAST
636   /* broadcast filter? */
637   if (!ip_get_option(pcb, SOF_BROADCAST) &&
638 #if LWIP_IPV6
639       !PCB_ISIPV6(pcb) &&
640 #endif /* LWIP_IPV6 */
641       ip_addr_isbroadcast(dst_ip, netif) ) {
642     LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
643       ("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
644     return ERR_VAL;
645   }
646 #endif /* IP_SOF_BROADCAST */
647
648   /* if the PCB is not yet bound to a port, bind it here */
649   if (pcb->local_port == 0) {
650     LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n"));
651     err = udp_bind(pcb, ipX_2_ip(&pcb->local_ip), pcb->local_port);
652     if (err != ERR_OK) {
653       LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n"));
654       return err;
655     }
656   }
657
658   /* not enough space to add an UDP header to first pbuf in given p chain? */
659   if (pbuf_header(p, UDP_HLEN)) {
660     /* allocate header in a separate new pbuf */
661     q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);
662     /* new header pbuf could not be allocated? */
663     if (q == NULL) {
664       LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n"));
665       return ERR_MEM;
666     }
667     if (p->tot_len != 0) {
668       /* chain header q in front of given pbuf p (only if p contains data) */
669       pbuf_chain(q, p);
670     }
671     /* first pbuf q points to header pbuf */
672     LWIP_DEBUGF(UDP_DEBUG,
673                 ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
674   } else {
675     /* adding space for header within p succeeded */
676     /* first pbuf q equals given pbuf */
677     q = p;
678     LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));
679   }
680   LWIP_ASSERT("check that first pbuf can hold struct udp_hdr",
681               (q->len >= sizeof(struct udp_hdr)));
682   /* q now represents the packet to be sent */
683   udphdr = (struct udp_hdr *)q->payload;
684   udphdr->src = htons(pcb->local_port);
685   udphdr->dest = htons(dst_port);
686   /* in UDP, 0 checksum means 'no checksum' */
687   udphdr->chksum = 0x0000; 
688
689   /* Multicast Loop? */
690 #if LWIP_IGMP
691   if (((pcb->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) &&
692 #if LWIP_IPV6
693       (
694 #if LWIP_IPV6_MLD
695        (PCB_ISIPV6(pcb) &&
696         ip6_addr_ismulticast(ip_2_ip6(dst_ip))) ||
697 #endif /* LWIP_IPV6_MLD */
698        (!PCB_ISIPV6(pcb) &&
699 #else /* LWIP_IPV6 */
700       ((
701 #endif /* LWIP_IPV6 */
702         ip_addr_ismulticast(dst_ip)))) {
703     q->flags |= PBUF_FLAG_MCASTLOOP;
704   }
705 #endif /* LWIP_IGMP */
706
707
708   /* PCB local address is IP_ANY_ADDR? */
709 #if LWIP_IPV6
710   if (PCB_ISIPV6(pcb)) {
711     if (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip))) {
712       src_ip = ip6_2_ip(ip6_select_source_address(netif, ip_2_ip6(dst_ip)));
713       if (src_ip == NULL) {
714         /* No suitable source address was found. */
715         if (q != p) {
716           /* free the header pbuf */
717           pbuf_free(q);
718           /* p is still referenced by the caller, and will live on */
719         }
720         return ERR_RTE;
721       }
722     } else {
723       /* use UDP PCB local IPv6 address as source address, if still valid. */
724       if (netif_matches_ip6_addr(netif, ipX_2_ip6(&pcb->local_ip)) < 0) {
725         /* Address isn't valid anymore. */
726         if (q != p) {
727           /* free the header pbuf */
728           pbuf_free(q);
729           /* p is still referenced by the caller, and will live on */
730         }
731         return ERR_RTE;
732       }
733       src_ip = ipX_2_ip(&pcb->local_ip);
734     }
735   }
736   else
737 #endif /* LWIP_IPV6 */
738   if (ip_addr_isany(ipX_2_ip(&pcb->local_ip))) {
739     /* use outgoing network interface IP address as source address */
740     src_ip = &(netif->ip_addr);
741   } else {
742     /* check if UDP PCB local IP address is correct
743      * this could be an old address if netif->ip_addr has changed */
744     if (!ip_addr_cmp(ipX_2_ip(&(pcb->local_ip)), &(netif->ip_addr))) {
745       /* local_ip doesn't match, drop the packet */
746       if (q != p) {
747         /* free the header pbuf */
748         pbuf_free(q);
749         q = NULL;
750         /* p is still referenced by the caller, and will live on */
751       }
752       return ERR_VAL;
753     }
754     /* use UDP PCB local IP address as source address */
755     src_ip = ipX_2_ip(&(pcb->local_ip));
756   }
757
758   LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len));
759
760 #if LWIP_UDPLITE
761   /* UDP Lite protocol? */
762   if (pcb->flags & UDP_FLAGS_UDPLITE) {
763     u16_t chklen, chklen_hdr;
764     LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len));
765     /* set UDP message length in UDP header */
766     chklen_hdr = chklen = pcb->chksum_len_tx;
767     if ((chklen < sizeof(struct udp_hdr)) || (chklen > q->tot_len)) {
768       if (chklen != 0) {
769         LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE pcb->chksum_len is illegal: %"U16_F"\n", chklen));
770       }
771       /* For UDP-Lite, checksum length of 0 means checksum
772          over the complete packet. (See RFC 3828 chap. 3.1)
773          At least the UDP-Lite header must be covered by the
774          checksum, therefore, if chksum_len has an illegal
775          value, we generate the checksum over the complete
776          packet to be safe. */
777       chklen_hdr = 0;
778       chklen = q->tot_len;
779     }
780     udphdr->len = htons(chklen_hdr);
781     /* calculate checksum */
782 #if CHECKSUM_GEN_UDP
783 #if LWIP_CHECKSUM_ON_COPY
784     if (have_chksum) {
785       chklen = UDP_HLEN;
786     }
787 #endif /* LWIP_CHECKSUM_ON_COPY */
788     udphdr->chksum = ipX_chksum_pseudo_partial(PCB_ISIPV6(pcb), q, IP_PROTO_UDPLITE,
789       q->tot_len, chklen, ip_2_ipX(src_ip), ip_2_ipX(dst_ip));
790 #if LWIP_CHECKSUM_ON_COPY
791     if (have_chksum) {
792       u32_t acc;
793       acc = udphdr->chksum + (u16_t)~(chksum);
794       udphdr->chksum = FOLD_U32T(acc);
795     }
796 #endif /* LWIP_CHECKSUM_ON_COPY */
797
798     /* chksum zero must become 0xffff, as zero means 'no checksum' */
799     if (udphdr->chksum == 0x0000) {
800       udphdr->chksum = 0xffff;
801     }
802 #endif /* CHECKSUM_GEN_UDP */
803
804     ip_proto = IP_PROTO_UDPLITE;
805   } else
806 #endif /* LWIP_UDPLITE */
807   {      /* UDP */
808     LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len));
809     udphdr->len = htons(q->tot_len);
810     /* calculate checksum */
811 #if CHECKSUM_GEN_UDP
812     /* Checksum is mandatory over IPv6. */
813     if (PCB_ISIPV6(pcb) || (pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
814       u16_t udpchksum;
815 #if LWIP_CHECKSUM_ON_COPY
816       if (have_chksum) {
817         u32_t acc;
818         udpchksum = ipX_chksum_pseudo_partial(PCB_ISIPV6(pcb), q, IP_PROTO_UDP,
819           q->tot_len, UDP_HLEN, ip_2_ipX(src_ip), ip_2_ipX(dst_ip));
820         acc = udpchksum + (u16_t)~(chksum);
821         udpchksum = FOLD_U32T(acc);
822       } else
823 #endif /* LWIP_CHECKSUM_ON_COPY */
824       {
825         udpchksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), q, IP_PROTO_UDP, q->tot_len,
826           ip_2_ipX(src_ip), ip_2_ipX(dst_ip));
827       }
828
829       /* chksum zero must become 0xffff, as zero means 'no checksum' */
830       if (udpchksum == 0x0000) {
831         udpchksum = 0xffff;
832       }
833       udphdr->chksum = udpchksum;
834     }
835 #endif /* CHECKSUM_GEN_UDP */
836     ip_proto = IP_PROTO_UDP;
837   }
838
839   LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum));
840   LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,0x%02"X16_F",)\n", (u16_t)ip_proto));
841   /* output to IP */
842   NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint));
843   err = ipX_output_if(PCB_ISIPV6(pcb), q, src_ip, dst_ip, pcb->ttl, pcb->tos, ip_proto, netif);
844   NETIF_SET_HWADDRHINT(netif, NULL);
845
846   /* TODO: must this be increased even if error occured? */
847   snmp_inc_udpoutdatagrams();
848
849   /* did we chain a separate header pbuf earlier? */
850   if (q != p) {
851     /* free the header pbuf */
852     pbuf_free(q);
853     q = NULL;
854     /* p is still referenced by the caller, and will live on */
855   }
856
857   UDP_STATS_INC(udp.xmit);
858   return err;
859 }
860
861 /**
862  * Bind an UDP PCB.
863  *
864  * @param pcb UDP PCB to be bound with a local address ipaddr and port.
865  * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to
866  * bind to all local interfaces.
867  * @param port local UDP port to bind with. Use 0 to automatically bind
868  * to a random port between UDP_LOCAL_PORT_RANGE_START and
869  * UDP_LOCAL_PORT_RANGE_END.
870  *
871  * ipaddr & port are expected to be in the same byte order as in the pcb.
872  *
873  * @return lwIP error code.
874  * - ERR_OK. Successful. No error occured.
875  * - ERR_USE. The specified ipaddr and port are already bound to by
876  * another UDP PCB.
877  *
878  * @see udp_disconnect()
879  */
880 err_t
881 udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
882 {
883   struct udp_pcb *ipcb;
884   u8_t rebind;
885
886   LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = "));
887   ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG | LWIP_DBG_TRACE, ip_2_ipX(ipaddr));
888   LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port));
889
890   rebind = 0;
891   /* Check for double bind and rebind of the same pcb */
892   for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
893     /* is this UDP PCB already on active list? */
894     if (pcb == ipcb) {
895       /* pcb may occur at most once in active list */
896       LWIP_ASSERT("rebind == 0", rebind == 0);
897       /* pcb already in list, just rebind */
898       rebind = 1;
899     }
900
901     /* By default, we don't allow to bind to a port that any other udp
902        PCB is alread bound to, unless *all* PCBs with that port have tha
903        REUSEADDR flag set. */
904 #if SO_REUSE
905     else if (!ip_get_option(pcb, SOF_REUSEADDR) &&
906              !ip_get_option(ipcb, SOF_REUSEADDR)) {
907 #else /* SO_REUSE */
908     /* port matches that of PCB in list and REUSEADDR not set -> reject */
909     else {
910 #endif /* SO_REUSE */
911       if ((ipcb->local_port == port) && IP_PCB_IPVER_EQ(pcb, ipcb) &&
912           /* IP address matches, or one is IP_ADDR_ANY? */
913             (ipX_addr_isany(PCB_ISIPV6(ipcb), &(ipcb->local_ip)) ||
914              ipX_addr_isany(PCB_ISIPV6(ipcb), ip_2_ipX(ipaddr)) ||
915              ipX_addr_cmp(PCB_ISIPV6(ipcb), &(ipcb->local_ip), ip_2_ipX(ipaddr)))) {
916         /* other PCB already binds to this local IP and port */
917         LWIP_DEBUGF(UDP_DEBUG,
918                     ("udp_bind: local port %"U16_F" already bound by another pcb\n", port));
919         return ERR_USE;
920       }
921     }
922   }
923
924   ipX_addr_set_ipaddr(PCB_ISIPV6(pcb), &pcb->local_ip, ipaddr);
925
926   /* no port specified? */
927   if (port == 0) {
928     port = udp_new_port();
929     if (port == 0) {
930       /* no more ports available in local range */
931       LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n"));
932       return ERR_USE;
933     }
934   }
935   pcb->local_port = port;
936   snmp_insert_udpidx_tree(pcb);
937   /* pcb not active yet? */
938   if (rebind == 0) {
939     /* place the PCB on the active list if not already there */
940     pcb->next = udp_pcbs;
941     udp_pcbs = pcb;
942   }
943   LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_bind: bound to "));
944   ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, &pcb->local_ip);
945   LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->local_port));
946   return ERR_OK;
947 }
948
949 /**
950  * Connect an UDP PCB.
951  *
952  * This will associate the UDP PCB with the remote address.
953  *
954  * @param pcb UDP PCB to be connected with remote address ipaddr and port.
955  * @param ipaddr remote IP address to connect with.
956  * @param port remote UDP port to connect with.
957  *
958  * @return lwIP error code
959  *
960  * ipaddr & port are expected to be in the same byte order as in the pcb.
961  *
962  * The udp pcb is bound to a random local port if not already bound.
963  *
964  * @see udp_disconnect()
965  */
966 err_t
967 udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
968 {
969   struct udp_pcb *ipcb;
970
971   if (pcb->local_port == 0) {
972     err_t err = udp_bind(pcb, ipX_2_ip(&pcb->local_ip), pcb->local_port);
973     if (err != ERR_OK) {
974       return err;
975     }
976   }
977
978   ipX_addr_set_ipaddr(PCB_ISIPV6(pcb), &pcb->remote_ip, ipaddr);
979   pcb->remote_port = port;
980   pcb->flags |= UDP_FLAGS_CONNECTED;
981 /** TODO: this functionality belongs in upper layers */
982 #ifdef LWIP_UDP_TODO
983 #if LWIP_IPV6
984   if (!PCB_ISIPV6(pcb))
985 #endif /* LWIP_IPV6 */
986   {
987     /* Nail down local IP for netconn_addr()/getsockname() */
988     if (ip_addr_isany(ipX_2_ip(&pcb->local_ip)) && !ip_addr_isany(ipX_2_ip(&pcb->remote_ip))) {
989       struct netif *netif;
990
991       if ((netif = ip_route(ipX_2_ip(&pcb->remote_ip))) == NULL) {
992         LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n",
993                     ip4_addr_get_u32(ipX_2_ip(&pcb->remote_ip))));
994         UDP_STATS_INC(udp.rterr);
995         return ERR_RTE;
996       }
997       /** TODO: this will bind the udp pcb locally, to the interface which
998           is used to route output packets to the remote address. However, we
999           might want to accept incoming packets on any interface! */
1000       ipX_addr_copy(0, pcb->local_ip, netif->ip_addr);
1001     } else if (ip_addr_isany(ipX_2_ip(&pcb->remote_ip))) {
1002       ipX_addr_set_any(0, &pcb->local_ip);
1003     }
1004   }
1005 #endif
1006   LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_connect: connected to "));
1007   ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
1008                        &pcb->remote_ip);
1009   LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->remote_port));
1010
1011   /* Insert UDP PCB into the list of active UDP PCBs. */
1012   for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
1013     if (pcb == ipcb) {
1014       /* already on the list, just return */
1015       return ERR_OK;
1016     }
1017   }
1018   /* PCB not yet on the list, add PCB now */
1019   pcb->next = udp_pcbs;
1020   udp_pcbs = pcb;
1021   return ERR_OK;
1022 }
1023
1024 /**
1025  * Disconnect a UDP PCB
1026  *
1027  * @param pcb the udp pcb to disconnect.
1028  */
1029 void
1030 udp_disconnect(struct udp_pcb *pcb)
1031 {
1032   /* reset remote address association */
1033   ipX_addr_set_any(PCB_ISIPV6(pcb), &pcb->remote_ip);
1034   pcb->remote_port = 0;
1035   /* mark PCB as unconnected */
1036   pcb->flags &= ~UDP_FLAGS_CONNECTED;
1037 }
1038
1039 /**
1040  * Set a receive callback for a UDP PCB
1041  *
1042  * This callback will be called when receiving a datagram for the pcb.
1043  *
1044  * @param pcb the pcb for wich to set the recv callback
1045  * @param recv function pointer of the callback function
1046  * @param recv_arg additional argument to pass to the callback function
1047  */
1048 void
1049 udp_recv(struct udp_pcb *pcb, udp_recv_fn recv, void *recv_arg)
1050 {
1051   /* remember recv() callback and user data */
1052   pcb->recv.ip4 = recv;
1053   pcb->recv_arg = recv_arg;
1054 }
1055
1056 /**
1057  * Remove an UDP PCB.
1058  *
1059  * @param pcb UDP PCB to be removed. The PCB is removed from the list of
1060  * UDP PCB's and the data structure is freed from memory.
1061  *
1062  * @see udp_new()
1063  */
1064 void
1065 udp_remove(struct udp_pcb *pcb)
1066 {
1067   struct udp_pcb *pcb2;
1068
1069   snmp_delete_udpidx_tree(pcb);
1070   /* pcb to be removed is first in list? */
1071   if (udp_pcbs == pcb) {
1072     /* make list start at 2nd pcb */
1073     udp_pcbs = udp_pcbs->next;
1074     /* pcb not 1st in list */
1075   } else {
1076     for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
1077       /* find pcb in udp_pcbs list */
1078       if (pcb2->next != NULL && pcb2->next == pcb) {
1079         /* remove pcb from list */
1080         pcb2->next = pcb->next;
1081       }
1082     }
1083   }
1084   memp_free(MEMP_UDP_PCB, pcb);
1085 }
1086
1087 /**
1088  * Create a UDP PCB.
1089  *
1090  * @return The UDP PCB which was created. NULL if the PCB data structure
1091  * could not be allocated.
1092  *
1093  * @see udp_remove()
1094  */
1095 struct udp_pcb *
1096 udp_new(void)
1097 {
1098   struct udp_pcb *pcb;
1099   pcb = (struct udp_pcb *)memp_malloc(MEMP_UDP_PCB);
1100   /* could allocate UDP PCB? */
1101   if (pcb != NULL) {
1102     /* UDP Lite: by initializing to all zeroes, chksum_len is set to 0
1103      * which means checksum is generated over the whole datagram per default
1104      * (recommended as default by RFC 3828). */
1105     /* initialize PCB to all zeroes */
1106     memset(pcb, 0, sizeof(struct udp_pcb));
1107     pcb->ttl = UDP_TTL;
1108   }
1109   return pcb;
1110 }
1111
1112 #if LWIP_IPV6
1113 /**
1114  * Create a UDP PCB for IPv6.
1115  *
1116  * @return The UDP PCB which was created. NULL if the PCB data structure
1117  * could not be allocated.
1118  *
1119  * @see udp_remove()
1120  */
1121 struct udp_pcb *
1122 udp_new_ip6(void)
1123 {
1124   struct udp_pcb *pcb;
1125   pcb = udp_new();
1126   ip_set_v6(pcb, 1);
1127   return pcb;
1128 }
1129 #endif /* LWIP_IPV6 */
1130
1131 #if UDP_DEBUG
1132 /**
1133  * Print UDP header information for debug purposes.
1134  *
1135  * @param udphdr pointer to the udp header in memory.
1136  */
1137 void
1138 udp_debug_print(struct udp_hdr *udphdr)
1139 {
1140   LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n"));
1141   LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
1142   LWIP_DEBUGF(UDP_DEBUG, ("|     %5"U16_F"     |     %5"U16_F"     | (src port, dest port)\n",
1143                           ntohs(udphdr->src), ntohs(udphdr->dest)));
1144   LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
1145   LWIP_DEBUGF(UDP_DEBUG, ("|     %5"U16_F"     |     0x%04"X16_F"    | (len, chksum)\n",
1146                           ntohs(udphdr->len), ntohs(udphdr->chksum)));
1147   LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
1148 }
1149 #endif /* UDP_DEBUG */
1150
1151 #endif /* LWIP_UDP */