]> git.sur5r.net Git - freertos/blob - Demo/lwIP_Demo_Rowley_ARM7/lwip-1.1.0/src/core/udp.c
First version under SVN is V4.0.1
[freertos] / Demo / lwIP_Demo_Rowley_ARM7 / lwip-1.1.0 / src / core / udp.c
1 /**
2  * @file
3  * User Datagram Protocol module
4  *
5  */
6 /*
7  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without modification,
11  * are permitted provided that the following conditions are met:
12  *
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.
20  *
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
30  * OF SUCH DAMAGE.
31  *
32  * This file is part of the lwIP TCP/IP stack.
33  *
34  * Author: Adam Dunkels <adam@sics.se>
35  *
36  */
37
38
39 /* udp.c
40  *
41  * The code for the User Datagram Protocol UDP.
42  *
43  */
44
45 #include <string.h>
46
47 #include "lwip/opt.h"
48
49 #include "lwip/def.h"
50 #include "lwip/memp.h"
51 #include "lwip/inet.h"
52 #include "lwip/ip_addr.h"
53 #include "lwip/netif.h"
54 #include "lwip/udp.h"
55 #include "lwip/icmp.h"
56
57 #include "lwip/stats.h"
58
59 #include "arch/perf.h"
60 #include "lwip/snmp.h"
61
62 /* The list of UDP PCBs */
63 #if LWIP_UDP
64 /* was static, but we may want to access this from a socket layer */
65 struct udp_pcb *udp_pcbs = NULL;
66
67 static struct udp_pcb *pcb_cache = NULL;
68
69
70 void
71 udp_init(void)
72 {
73   udp_pcbs = pcb_cache = NULL;
74 }
75
76 /**
77  * Process an incoming UDP datagram.
78  *
79  * Given an incoming UDP datagram (as a chain of pbufs) this function
80  * finds a corresponding UDP PCB and
81  *
82  * @param pbuf pbuf to be demultiplexed to a UDP PCB.
83  * @param netif network interface on which the datagram was received.
84  *
85  */
86 void
87 udp_input(struct pbuf *p, struct netif *inp)
88 {
89   struct udp_hdr *udphdr;
90   struct udp_pcb *pcb;
91   struct ip_hdr *iphdr;
92   u16_t src, dest;
93
94 #if SO_REUSE
95   struct udp_pcb *pcb_temp;
96   int reuse = 0;
97   int reuse_port_1 = 0;
98   int reuse_port_2 = 0;
99 #endif /* SO_REUSE */
100   
101   PERF_START;
102
103   UDP_STATS_INC(udp.recv);
104
105   iphdr = p->payload;
106
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();
113     pbuf_free(p);
114     goto end;
115   }
116
117   udphdr = (struct udp_hdr *)((u8_t *)p->payload - UDP_HLEN);
118
119   LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %u\n", p->tot_len));
120
121   src = ntohs(udphdr->src);
122   dest = ntohs(udphdr->dest);
123
124   udp_debug_print(udphdr);
125
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)));
132
133 #if SO_REUSE
134   pcb_temp = udp_pcbs;
135   
136  again_1:
137   
138   /* Iterate through the UDP pcb list for a fully matching pcb */
139   for (pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {
140 #else  /* SO_REUSE */ 
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));
150
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)))) {
163 #if SO_REUSE
164       if (pcb->so_options & SOF_REUSEPORT) {
165         if(reuse) {
166           /* We processed one PCB already */
167           LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB and SOF_REUSEPORT set.\n"));
168         } else {
169           /* First PCB with this address */
170           LWIP_DEBUGF(UDP_DEBUG, ("udp_input: first PCB and SOF_REUSEPORT set.\n"));
171           reuse = 1;
172         }
173         
174         reuse_port_1 = 1; 
175         p->ref++;
176         LWIP_DEBUGF(UDP_DEBUG, ("udp_input: reference counter on PBUF set to %i\n", p->ref));
177       } else {
178         if (reuse) {
179           /* We processed one PCB already */
180           LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB but SOF_REUSEPORT not set !\n"));
181         }
182       }
183 #endif /* SO_REUSE */
184       break;
185     }
186   }
187   /* no fully matching pcb found? then look for an unconnected pcb */
188   if (pcb == NULL) {
189     /* Iterate through the UDP PCB list for a pcb that matches
190        the local address. */
191
192 #if SO_REUSE
193     pcb_temp = udp_pcbs;
194     
195   again_2:
196
197     for (pcb = pcb_temp; pcb != NULL; pcb = pcb->next) {
198 #else  /* SO_REUSE */ 
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));
206       /* unconnected? */
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)))) {
214 #if SO_REUSE
215         if (pcb->so_options & SOF_REUSEPORT) {
216           if (reuse) {
217             /* We processed one PCB already */
218             LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB and SOF_REUSEPORT set.\n"));
219           } else {
220             /* First PCB with this address */
221             LWIP_DEBUGF(UDP_DEBUG, ("udp_input: first PCB and SOF_REUSEPORT set.\n"));
222             reuse = 1;
223           }
224           
225           reuse_port_2 = 1; 
226           p->ref++;
227           LWIP_DEBUGF(UDP_DEBUG, ("udp_input: reference counter on PBUF set to %i\n", p->ref));
228         } else {
229           if (reuse) {
230             /* We processed one PCB already */
231             LWIP_DEBUGF(UDP_DEBUG, ("udp_input: second or later PCB but SOF_REUSEPORT not set !\n"));
232           }
233         }
234 #endif /* SO_REUSE */
235         break;
236       }
237     }
238   }
239
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))
242     {
243     LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: calculating checksum\n"));
244     pbuf_header(p, UDP_HLEN);
245 #ifdef IPv6
246     if (iphdr->nexthdr == IP_PROTO_UDPLITE) {
247 #else
248     if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
249 #endif /* IPv4 */
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();
259   pbuf_free(p);
260   goto end;
261       }
262 #endif
263     } else {
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"));
270
271     UDP_STATS_INC(udp.chkerr);
272     UDP_STATS_INC(udp.drop);
273     snmp_inc_udpinerrors();
274     pbuf_free(p);
275     goto end;
276   }
277       }
278 #endif
279     }
280     pbuf_header(p, -UDP_HLEN);
281     if (pcb != NULL) {
282       snmp_inc_udpindatagrams();
283       pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);
284 #if SO_REUSE
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;
289         
290         if(reuse_port_1) {
291           /* We are searching connected sockets */
292           reuse_port_1 = 0;
293           reuse_port_2 = 0;
294           goto again_1;
295         } else {
296           /* We are searching unconnected sockets */
297           reuse_port_1 = 0;
298           reuse_port_2 = 0;
299           goto again_2;
300         }
301       }
302 #endif /* SO_REUSE */ 
303     } else {
304 #if SO_REUSE
305       if(reuse) {
306         LWIP_DEBUGF(UDP_DEBUG, ("udp_input: freeing PBUF with reference counter set to %i\n", p->ref));
307         pbuf_free(p);
308         goto end;
309       }
310 #endif /* SO_REUSE */
311       LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: not for us.\n"));
312
313       /* No match was found, send ICMP destination port unreachable unless
314       destination address was broadcast/multicast. */
315
316       if (!ip_addr_isbroadcast(&iphdr->dest, inp) &&
317           !ip_addr_ismulticast(&iphdr->dest)) {
318
319   /* adjust pbuf pointer */
320   p->payload = iphdr;
321   icmp_dest_unreach(p, ICMP_DUR_PORT);
322       }
323       UDP_STATS_INC(udp.proterr);
324       UDP_STATS_INC(udp.drop);
325     snmp_inc_udpnoports();
326       pbuf_free(p);
327     }
328   } else {
329     pbuf_free(p);
330   }
331   end:
332
333   PERF_STOP("udp_input");
334 }
335
336 /**
337  * Send data to a specified address using UDP.
338  *
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.
343  *
344  * If the PCB already has a remote address association, it will
345  * be restored after the data is sent.
346  * 
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.
351  *
352  * @see udp_disconnect() udp_send()
353  */
354 err_t
355 udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
356   struct ip_addr *dst_ip, u16_t dst_port)
357 {
358   err_t err;
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;
373   return err;
374 }
375
376 /**
377  * Send data using UDP.
378  *
379  * @param pcb UDP PCB used to send the data.
380  * @param pbuf chain of pbuf's to be sent.
381  *
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.
386  *
387  * @see udp_disconnect() udp_sendto()
388  */
389 err_t
390 udp_send(struct udp_pcb *pcb, struct pbuf *p)
391 {
392   struct udp_hdr *udphdr;
393   struct netif *netif;
394   struct ip_addr *src_ip;
395   err_t err;
396   struct pbuf *q; /* q will be sent down the stack */
397
398   LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_send\n"));
399
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);
404     if (err != ERR_OK) {
405       LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: forced port bind failed\n"));
406       return err;
407     }
408   }
409
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? */
415     if (q == NULL) {
416       LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: could not allocate header\n"));
417       return ERR_MEM;
418     }
419     /* chain header q in front of given pbuf p */
420     pbuf_chain(q, 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 */
424   } else {
425     /* first pbuf q equals given pbuf */
426     q = p;
427     LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));
428   }
429   /* { q now represents the packet to be sent } */
430   udphdr = q->payload;
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; 
435
436   /* find the outgoing network interface for this packet */
437   netif = ip_route(&(pcb->remote_ip));
438   /* no outgoing network interface could be found? */
439   if (netif == NULL) {
440     LWIP_DEBUGF(UDP_DEBUG | 1, ("udp_send: No route to 0x%lx\n", pcb->remote_ip.addr));
441     UDP_STATS_INC(udp.rterr);
442     return ERR_RTE;
443   }
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);
448   } else {
449     /* use UDP PCB local IP address as source address */
450     src_ip = &(pcb->local_ip);
451   }
452
453   LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %u\n", q->tot_len));
454
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 */
461 #if CHECKSUM_GEN_UDP
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;
466 #else
467     udphdr->chksum = 0x0000;
468 #endif
469     /* output to IP */
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);    
472   /* UDP */
473   } else {
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 */
477 #if CHECKSUM_GEN_UDP
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;
482     }
483 #else
484     udphdr->chksum = 0x0000;
485 #endif
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"));
488     /* output to IP */
489     err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);    
490   }
491   /* TODO: must this be increased even if error occured? */
492   snmp_inc_udpoutdatagrams();
493
494   /* did we chain a seperate header pbuf earlier? */
495   if (q != p) {
496     /* free the header pbuf */
497     pbuf_free(q); q = NULL;
498     /* { p is still referenced by the caller, and will live on } */
499   }
500
501   UDP_STATS_INC(udp.xmit);
502   return err;
503 }
504
505 /**
506  * Bind an UDP PCB.
507  *
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.
512  *
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
516  * another UDP PCB.
517  *
518  * @see udp_disconnect()
519  */
520 err_t
521 udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
522 {
523   struct udp_pcb *ipcb;
524   u8_t rebind;
525 #if SO_REUSE
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));
531
532   rebind = 0;
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? */
536     if (pcb == ipcb) {
537       /* pcb may occur at most once in active list */
538       LWIP_ASSERT("rebind == 0", rebind == 0);
539       /* pcb already in list, just rebind */
540       rebind = 1;
541     }
542
543 #if SO_REUSE == 0
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. */
548 #ifdef LWIP_UDP_TODO
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));
557       return ERR_USE;
558     }
559 #endif
560
561 #else /* SO_REUSE */
562       /* Search through list of PCB's. 
563          
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.
568       
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.
571       
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));
579         }
580         else {
581           LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: in UDP PCB's SO_REUSEPORT not set and same address.\n"));
582           return ERR_USE;
583         }
584       }
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"));
589           return ERR_USE;
590         }           
591       }
592     }
593 #endif /* SO_REUSE */
594
595   }
596
597 #if 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"));
602     return ERR_USE;
603   }
604 #endif /* SO_REUSE */
605
606   ip_addr_set(&pcb->local_ip, ipaddr);
607   /* no port specified? */
608   if (port == 0) {
609 #ifndef UDP_LOCAL_PORT_RANGE_START
610 #define UDP_LOCAL_PORT_RANGE_START 4096
611 #define UDP_LOCAL_PORT_RANGE_END   0x7fff
612 #endif
613     port = UDP_LOCAL_PORT_RANGE_START;
614     ipcb = udp_pcbs;
615     while ((ipcb != NULL) && (port != UDP_LOCAL_PORT_RANGE_END)) {
616       if (ipcb->local_port == port) {
617         port++;
618         ipcb = udp_pcbs;
619       } else
620         ipcb = ipcb->next;
621     }
622     if (ipcb != NULL) {
623       /* no more ports available in local range */
624       LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n"));
625       return ERR_USE;
626     }
627   }
628   pcb->local_port = port;
629   /* pcb not active yet? */
630   if (rebind == 0) {
631     /* place the PCB on the active list if not already there */
632     pcb->next = udp_pcbs;
633     udp_pcbs = pcb;
634   }
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));
640   return ERR_OK;
641 }
642 /**
643  * Connect an UDP PCB.
644  *
645  * This will associate the UDP PCB with the remote address.
646  *
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.
650  *
651  * @return lwIP error code
652  *
653  * @see udp_disconnect()
654  */
655 err_t
656 udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
657 {
658   struct udp_pcb *ipcb;
659
660   if (pcb->local_port == 0) {
661     err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
662     if (err != ERR_OK)
663       return err;
664   }
665
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 */
670 #ifdef LWIP_UDP_TODO
671   /* Nail down local IP for netconn_addr()/getsockname() */
672   if (ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) {
673     struct netif *netif;
674
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);
678       return ERR_RTE;
679     }
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;
686   }
687 #endif
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));
693
694   /* Insert UDP PCB into the list of active UDP PCBs. */
695   for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
696     if (pcb == ipcb) {
697       /* already on the list, just return */
698       return ERR_OK;
699     }
700   }
701   /* PCB not yet on the list, add PCB now */
702   pcb->next = udp_pcbs;
703   udp_pcbs = pcb;
704   return ERR_OK;
705 }
706
707 void
708 udp_disconnect(struct udp_pcb *pcb)
709 {
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;
715 }
716
717 void
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),
721    void *recv_arg)
722 {
723   /* remember recv() callback and user data */
724   pcb->recv = recv;
725   pcb->recv_arg = recv_arg;
726 }
727 /**
728  * Remove an UDP PCB.
729  *
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.
732  *
733  * @see udp_new()
734  */
735 void
736 udp_remove(struct udp_pcb *pcb)
737 {
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;
749     }
750   }
751   memp_free(MEMP_UDP_PCB, pcb);
752 }
753 /**
754  * Create a UDP PCB.
755  *
756  * @return The UDP PCB which was created. NULL if the PCB data structure
757  * could not be allocated.
758  *
759  * @see udp_remove()
760  */
761 struct udp_pcb *
762 udp_new(void) {
763   struct udp_pcb *pcb;
764   pcb = memp_malloc(MEMP_UDP_PCB);
765   /* could allocate UDP PCB? */
766   if (pcb != NULL) {
767     /* initialize PCB to all zeroes */
768     memset(pcb, 0, sizeof(struct udp_pcb));
769     pcb->ttl = UDP_TTL;
770   }
771   
772   
773   return pcb;
774 }
775
776 #if UDP_DEBUG
777 int
778 udp_debug_print(struct udp_hdr *udphdr)
779 {
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"));
788   return 0;
789 }
790 #endif /* UDP_DEBUG */
791
792 #endif /* LWIP_UDP */
793
794
795
796
797
798
799
800
801