Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-os by
lwip_udp.c
00001 /** 00002 * @file 00003 * User Datagram Protocol module\n 00004 * See also @ref udp_raw 00005 */ 00006 00007 /* 00008 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 00009 * All rights reserved. 00010 * 00011 * Redistribution and use in source and binary forms, with or without modification, 00012 * are permitted provided that the following conditions are met: 00013 * 00014 * 1. Redistributions of source code must retain the above copyright notice, 00015 * this list of conditions and the following disclaimer. 00016 * 2. Redistributions in binary form must reproduce the above copyright notice, 00017 * this list of conditions and the following disclaimer in the documentation 00018 * and/or other materials provided with the distribution. 00019 * 3. The name of the author may not be used to endorse or promote products 00020 * derived from this software without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 00023 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00024 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00025 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00026 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00027 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00028 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00029 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00030 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00031 * OF SUCH DAMAGE. 00032 * 00033 * This file is part of the lwIP TCP/IP stack. 00034 * 00035 * Author: Adam Dunkels <adam@sics.se> 00036 * 00037 */ 00038 00039 /** 00040 * @defgroup udp_raw UDP 00041 * @ingroup raw_api 00042 * User Datagram Protocol module\n 00043 * @see @ref raw_api and @ref netconn 00044 */ 00045 00046 /* udp.c 00047 * 00048 * The code for the User Datagram Protocol UDP & UDPLite (RFC 3828). 00049 * 00050 */ 00051 00052 /* @todo Check the use of '(struct udp_pcb).chksum_len_rx'! 00053 */ 00054 00055 #include "lwip/opt.h" 00056 00057 #if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ 00058 00059 #include "lwip/udp.h" 00060 #include "lwip/def.h" 00061 #include "lwip/memp.h" 00062 #include "lwip/inet_chksum.h" 00063 #include "lwip/ip_addr.h" 00064 #include "lwip/ip6.h" 00065 #include "lwip/ip6_addr.h" 00066 #include "lwip/inet_chksum.h" 00067 #include "lwip/netif.h" 00068 #include "lwip/icmp.h" 00069 #include "lwip/icmp6.h" 00070 #include "lwip/stats.h" 00071 #include "lwip/snmp.h" 00072 #include "lwip/dhcp.h" 00073 00074 #include <string.h> 00075 00076 #ifndef UDP_LOCAL_PORT_RANGE_START 00077 /* From http://www.iana.org/assignments/port-numbers: 00078 "The Dynamic and/or Private Ports are those from 49152 through 65535" */ 00079 #define UDP_LOCAL_PORT_RANGE_START 0xc000 00080 #define UDP_LOCAL_PORT_RANGE_END 0xffff 00081 #define UDP_ENSURE_LOCAL_PORT_RANGE(port) ((u16_t)(((port) & ~UDP_LOCAL_PORT_RANGE_START) + UDP_LOCAL_PORT_RANGE_START)) 00082 #endif 00083 00084 /* last local UDP port */ 00085 static u16_t udp_port = UDP_LOCAL_PORT_RANGE_START; 00086 00087 /* The list of UDP PCBs */ 00088 /* exported in udp.h (was static) */ 00089 struct udp_pcb *udp_pcbs; 00090 00091 /** 00092 * Initialize this module. 00093 */ 00094 void 00095 udp_init(void) 00096 { 00097 #if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) 00098 udp_port = UDP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); 00099 #endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ 00100 } 00101 00102 /** 00103 * Allocate a new local UDP port. 00104 * 00105 * @return a new (free) local UDP port number 00106 */ 00107 static u16_t 00108 udp_new_port(void) 00109 { 00110 u16_t n = 0; 00111 struct udp_pcb *pcb; 00112 00113 again: 00114 if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) { 00115 udp_port = UDP_LOCAL_PORT_RANGE_START; 00116 } 00117 /* Check all PCBs. */ 00118 for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { 00119 if (pcb->local_port == udp_port) { 00120 if (++n > (UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START)) { 00121 return 0; 00122 } 00123 goto again; 00124 } 00125 } 00126 return udp_port; 00127 #if 0 00128 struct udp_pcb *ipcb = udp_pcbs; 00129 while ((ipcb != NULL) && (udp_port != UDP_LOCAL_PORT_RANGE_END)) { 00130 if (ipcb->local_port == udp_port) { 00131 /* port is already used by another udp_pcb */ 00132 udp_port++; 00133 /* restart scanning all udp pcbs */ 00134 ipcb = udp_pcbs; 00135 } else { 00136 /* go on with next udp pcb */ 00137 ipcb = ipcb->next; 00138 } 00139 } 00140 if (ipcb != NULL) { 00141 return 0; 00142 } 00143 return udp_port; 00144 #endif 00145 } 00146 00147 /** Common code to see if the current input packet matches the pcb 00148 * (current input packet is accessed via ip(4/6)_current_* macros) 00149 * 00150 * @param pcb pcb to check 00151 * @param inp network interface on which the datagram was received (only used for IPv4) 00152 * @param broadcast 1 if his is an IPv4 broadcast (global or subnet-only), 0 otherwise (only used for IPv4) 00153 * @return 1 on match, 0 otherwise 00154 */ 00155 static u8_t 00156 udp_input_local_match(struct udp_pcb *pcb, struct netif *inp, u8_t broadcast) 00157 { 00158 LWIP_UNUSED_ARG(inp); /* in IPv6 only case */ 00159 LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */ 00160 00161 /* Dual-stack: PCBs listening to any IP type also listen to any IP address */ 00162 if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) { 00163 #if LWIP_IPV4 && IP_SOF_BROADCAST_RECV 00164 if ((broadcast != 0) && !ip_get_option(pcb, SOF_BROADCAST)) { 00165 return 0; 00166 } 00167 #endif /* LWIP_IPV4 && IP_SOF_BROADCAST_RECV */ 00168 return 1; 00169 } 00170 00171 /* Only need to check PCB if incoming IP version matches PCB IP version */ 00172 if (IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ip_current_dest_addr())) { 00173 #if LWIP_IPV4 00174 /* Special case: IPv4 broadcast: all or broadcasts in my subnet 00175 * Note: broadcast variable can only be 1 if it is an IPv4 broadcast */ 00176 if (broadcast != 0) { 00177 #if IP_SOF_BROADCAST_RECV 00178 if (ip_get_option(pcb, SOF_BROADCAST)) 00179 #endif /* IP_SOF_BROADCAST_RECV */ 00180 { 00181 if (ip4_addr_isany(ip_2_ip4(&pcb->local_ip)) || 00182 ((ip4_current_dest_addr()->addr == IPADDR_BROADCAST)) || 00183 ip4_addr_netcmp(ip_2_ip4(&pcb->local_ip), ip4_current_dest_addr(), netif_ip4_netmask(inp))) { 00184 return 1; 00185 } 00186 } 00187 } else 00188 #endif /* LWIP_IPV4 */ 00189 /* Handle IPv4 and IPv6: all, multicast or exact match */ 00190 if (ip_addr_isany(&pcb->local_ip) || 00191 #if LWIP_IPV6_MLD 00192 (ip_current_is_v6() && ip6_addr_ismulticast(ip6_current_dest_addr())) || 00193 #endif /* LWIP_IPV6_MLD */ 00194 #if LWIP_IGMP 00195 (!ip_current_is_v6() && ip4_addr_ismulticast(ip4_current_dest_addr())) || 00196 #endif /* LWIP_IGMP */ 00197 ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) { 00198 return 1; 00199 } 00200 } 00201 00202 return 0; 00203 } 00204 00205 /** 00206 * Process an incoming UDP datagram. 00207 * 00208 * Given an incoming UDP datagram (as a chain of pbufs) this function 00209 * finds a corresponding UDP PCB and hands over the pbuf to the pcbs 00210 * recv function. If no pcb is found or the datagram is incorrect, the 00211 * pbuf is freed. 00212 * 00213 * @param p pbuf to be demultiplexed to a UDP PCB (p->payload pointing to the UDP header) 00214 * @param inp network interface on which the datagram was received. 00215 * 00216 */ 00217 void 00218 udp_input(struct pbuf *p, struct netif *inp) 00219 { 00220 struct udp_hdr *udphdr; 00221 struct udp_pcb *pcb, *prev; 00222 struct udp_pcb *uncon_pcb; 00223 u16_t src, dest; 00224 u8_t broadcast; 00225 u8_t for_us = 0; 00226 00227 LWIP_UNUSED_ARG(inp); 00228 00229 PERF_START; 00230 00231 UDP_STATS_INC(udp.recv); 00232 00233 /* Check minimum length (UDP header) */ 00234 if (p->len < UDP_HLEN) { 00235 /* drop short packets */ 00236 LWIP_DEBUGF(UDP_DEBUG, 00237 ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len)); 00238 UDP_STATS_INC(udp.lenerr); 00239 UDP_STATS_INC(udp.drop); 00240 MIB2_STATS_INC(mib2.udpinerrors); 00241 pbuf_free(p); 00242 goto end; 00243 } 00244 00245 udphdr = (struct udp_hdr *)p->payload; 00246 00247 /* is broadcast packet ? */ 00248 broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif()); 00249 00250 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len)); 00251 00252 /* convert src and dest ports to host byte order */ 00253 src = ntohs(udphdr->src); 00254 dest = ntohs(udphdr->dest); 00255 00256 udp_debug_print(udphdr); 00257 00258 /* print the UDP source and destination */ 00259 LWIP_DEBUGF(UDP_DEBUG, ("udp (")); 00260 ip_addr_debug_print(UDP_DEBUG, ip_current_dest_addr()); 00261 LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", ntohs(udphdr->dest))); 00262 ip_addr_debug_print(UDP_DEBUG, ip_current_src_addr()); 00263 LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", ntohs(udphdr->src))); 00264 00265 pcb = NULL; 00266 prev = NULL; 00267 uncon_pcb = NULL; 00268 /* Iterate through the UDP pcb list for a matching pcb. 00269 * 'Perfect match' pcbs (connected to the remote port & ip address) are 00270 * preferred. If no perfect match is found, the first unconnected pcb that 00271 * matches the local port and ip address gets the datagram. */ 00272 for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { 00273 /* print the PCB local and remote address */ 00274 LWIP_DEBUGF(UDP_DEBUG, ("pcb (")); 00275 ip_addr_debug_print(UDP_DEBUG, &pcb->local_ip); 00276 LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", pcb->local_port)); 00277 ip_addr_debug_print(UDP_DEBUG, &pcb->remote_ip); 00278 LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", pcb->remote_port)); 00279 00280 /* compare PCB local addr+port to UDP destination addr+port */ 00281 if ((pcb->local_port == dest) && 00282 (udp_input_local_match(pcb, inp, broadcast) != 0)) { 00283 if (((pcb->flags & UDP_FLAGS_CONNECTED) == 0) && 00284 ((uncon_pcb == NULL) 00285 #if SO_REUSE 00286 /* prefer specific IPs over cath-all */ 00287 || !ip_addr_isany(&pcb->local_ip) 00288 #endif /* SO_REUSE */ 00289 )) { 00290 /* the first unconnected matching PCB */ 00291 uncon_pcb = pcb; 00292 } 00293 00294 /* compare PCB remote addr+port to UDP source addr+port */ 00295 if ((pcb->remote_port == src) && 00296 (ip_addr_isany_val(pcb->remote_ip) || 00297 ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()))) { 00298 /* the first fully matching PCB */ 00299 if (prev != NULL) { 00300 /* move the pcb to the front of udp_pcbs so that is 00301 found faster next time */ 00302 prev->next = pcb->next; 00303 pcb->next = udp_pcbs; 00304 udp_pcbs = pcb; 00305 } else { 00306 UDP_STATS_INC(udp.cachehit); 00307 } 00308 break; 00309 } 00310 } 00311 00312 prev = pcb; 00313 } 00314 /* no fully matching pcb found? then look for an unconnected pcb */ 00315 if (pcb == NULL) { 00316 pcb = uncon_pcb; 00317 } 00318 00319 /* Check checksum if this is a match or if it was directed at us. */ 00320 if (pcb != NULL) { 00321 for_us = 1; 00322 } else { 00323 #if LWIP_IPV6 00324 if (ip_current_is_v6()) { 00325 for_us = netif_get_ip6_addr_match(inp, ip6_current_dest_addr()) >= 0; 00326 } 00327 #endif /* LWIP_IPV6 */ 00328 #if LWIP_IPV4 00329 if (!ip_current_is_v6()) { 00330 for_us = ip4_addr_cmp(netif_ip4_addr(inp), ip4_current_dest_addr()); 00331 } 00332 #endif /* LWIP_IPV4 */ 00333 } 00334 00335 if (for_us) { 00336 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n")); 00337 #if CHECKSUM_CHECK_UDP 00338 IF__NETIF_CHECKSUM_ENABLED(inp, CHECKSUM_CHECK_UDP) { 00339 #if LWIP_UDPLITE 00340 if (ip_current_header_proto() == IP_PROTO_UDPLITE) { 00341 /* Do the UDP Lite checksum */ 00342 u16_t chklen = ntohs(udphdr->len); 00343 if (chklen < sizeof(struct udp_hdr)) { 00344 if (chklen == 0) { 00345 /* For UDP-Lite, checksum length of 0 means checksum 00346 over the complete packet (See RFC 3828 chap. 3.1) */ 00347 chklen = p->tot_len; 00348 } else { 00349 /* At least the UDP-Lite header must be covered by the 00350 checksum! (Again, see RFC 3828 chap. 3.1) */ 00351 goto chkerr; 00352 } 00353 } 00354 if (ip_chksum_pseudo_partial(p, IP_PROTO_UDPLITE, 00355 p->tot_len, chklen, 00356 ip_current_src_addr(), ip_current_dest_addr()) != 0) { 00357 goto chkerr; 00358 } 00359 } else 00360 #endif /* LWIP_UDPLITE */ 00361 { 00362 if (udphdr->chksum != 0) { 00363 if (ip_chksum_pseudo(p, IP_PROTO_UDP, p->tot_len, 00364 ip_current_src_addr(), 00365 ip_current_dest_addr()) != 0) { 00366 goto chkerr; 00367 } 00368 } 00369 } 00370 } 00371 #endif /* CHECKSUM_CHECK_UDP */ 00372 if (pbuf_header(p, -UDP_HLEN)) { 00373 /* Can we cope with this failing? Just assert for now */ 00374 LWIP_ASSERT("pbuf_header failed\n", 0); 00375 UDP_STATS_INC(udp.drop); 00376 MIB2_STATS_INC(mib2.udpinerrors); 00377 pbuf_free(p); 00378 goto end; 00379 } 00380 00381 if (pcb != NULL) { 00382 MIB2_STATS_INC(mib2.udpindatagrams); 00383 #if SO_REUSE && SO_REUSE_RXTOALL 00384 if (ip_get_option(pcb, SOF_REUSEADDR) && 00385 (broadcast || ip_addr_ismulticast(ip_current_dest_addr()))) { 00386 /* pass broadcast- or multicast packets to all multicast pcbs 00387 if SOF_REUSEADDR is set on the first match */ 00388 struct udp_pcb *mpcb; 00389 u8_t p_header_changed = 0; 00390 s16_t hdrs_len = (s16_t)(ip_current_header_tot_len() + UDP_HLEN); 00391 for (mpcb = udp_pcbs; mpcb != NULL; mpcb = mpcb->next) { 00392 if (mpcb != pcb) { 00393 /* compare PCB local addr+port to UDP destination addr+port */ 00394 if ((mpcb->local_port == dest) && 00395 (udp_input_local_match(mpcb, inp, broadcast) != 0)) { 00396 /* pass a copy of the packet to all local matches */ 00397 if (mpcb->recv != NULL) { 00398 struct pbuf *q; 00399 /* for that, move payload to IP header again */ 00400 if (p_header_changed == 0) { 00401 pbuf_header_force(p, hdrs_len); 00402 p_header_changed = 1; 00403 } 00404 q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); 00405 if (q != NULL) { 00406 err_t err = pbuf_copy(q, p); 00407 if (err == ERR_OK) { 00408 /* move payload to UDP data */ 00409 pbuf_header(q, -hdrs_len); 00410 mpcb->recv(mpcb->recv_arg, mpcb, q, ip_current_src_addr(), src); 00411 } 00412 } 00413 } 00414 } 00415 } 00416 } 00417 if (p_header_changed) { 00418 /* and move payload to UDP data again */ 00419 pbuf_header(p, -hdrs_len); 00420 } 00421 } 00422 #endif /* SO_REUSE && SO_REUSE_RXTOALL */ 00423 /* callback */ 00424 if (pcb->recv != NULL) { 00425 /* now the recv function is responsible for freeing p */ 00426 pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr(), src); 00427 } else { 00428 /* no recv function registered? then we have to free the pbuf! */ 00429 pbuf_free(p); 00430 goto end; 00431 } 00432 } else { 00433 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: not for us.\n")); 00434 00435 #if LWIP_ICMP || LWIP_ICMP6 00436 /* No match was found, send ICMP destination port unreachable unless 00437 destination address was broadcast/multicast. */ 00438 if (!broadcast && !ip_addr_ismulticast(ip_current_dest_addr())) { 00439 /* move payload pointer back to ip header */ 00440 pbuf_header_force(p, ip_current_header_tot_len() + UDP_HLEN); 00441 icmp_port_unreach(ip_current_is_v6(), p); 00442 } 00443 #endif /* LWIP_ICMP || LWIP_ICMP6 */ 00444 UDP_STATS_INC(udp.proterr); 00445 UDP_STATS_INC(udp.drop); 00446 MIB2_STATS_INC(mib2.udpnoports); 00447 pbuf_free(p); 00448 } 00449 } else { 00450 pbuf_free(p); 00451 } 00452 end: 00453 PERF_STOP("udp_input"); 00454 return; 00455 #if CHECKSUM_CHECK_UDP 00456 chkerr: 00457 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00458 ("udp_input: UDP (or UDP Lite) datagram discarded due to failing checksum\n")); 00459 UDP_STATS_INC(udp.chkerr); 00460 UDP_STATS_INC(udp.drop); 00461 MIB2_STATS_INC(mib2.udpinerrors); 00462 pbuf_free(p); 00463 PERF_STOP("udp_input"); 00464 #endif /* CHECKSUM_CHECK_UDP */ 00465 } 00466 00467 /** 00468 * @ingroup udp_raw 00469 * Send data using UDP. 00470 * 00471 * @param pcb UDP PCB used to send the data. 00472 * @param p chain of pbuf's to be sent. 00473 * 00474 * The datagram will be sent to the current remote_ip & remote_port 00475 * stored in pcb. If the pcb is not bound to a port, it will 00476 * automatically be bound to a random port. 00477 * 00478 * @return lwIP error code. 00479 * - ERR_OK. Successful. No error occurred. 00480 * - ERR_MEM. Out of memory. 00481 * - ERR_RTE. Could not find route to destination address. 00482 * - ERR_VAL. No PCB or PCB is dual-stack 00483 * - More errors could be returned by lower protocol layers. 00484 * 00485 * @see udp_disconnect() udp_sendto() 00486 */ 00487 err_t 00488 udp_send(struct udp_pcb *pcb, struct pbuf *p) 00489 { 00490 if ((pcb == NULL) || IP_IS_ANY_TYPE_VAL(pcb->remote_ip)) { 00491 return ERR_VAL; 00492 } 00493 00494 /* send to the packet using remote ip and port stored in the pcb */ 00495 return udp_sendto(pcb, p, &pcb->remote_ip, pcb->remote_port); 00496 } 00497 00498 #if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP 00499 /** @ingroup udp_raw 00500 * Same as udp_send() but with checksum 00501 */ 00502 err_t 00503 udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, 00504 u8_t have_chksum, u16_t chksum) 00505 { 00506 if ((pcb == NULL) || IP_IS_ANY_TYPE_VAL(pcb->remote_ip)) { 00507 return ERR_VAL; 00508 } 00509 00510 /* send to the packet using remote ip and port stored in the pcb */ 00511 return udp_sendto_chksum(pcb, p, &pcb->remote_ip, pcb->remote_port, 00512 have_chksum, chksum); 00513 } 00514 #endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ 00515 00516 /** 00517 * @ingroup udp_raw 00518 * Send data to a specified address using UDP. 00519 * 00520 * @param pcb UDP PCB used to send the data. 00521 * @param p chain of pbuf's to be sent. 00522 * @param dst_ip Destination IP address. 00523 * @param dst_port Destination UDP port. 00524 * 00525 * dst_ip & dst_port are expected to be in the same byte order as in the pcb. 00526 * 00527 * If the PCB already has a remote address association, it will 00528 * be restored after the data is sent. 00529 * 00530 * @return lwIP error code (@see udp_send for possible error codes) 00531 * 00532 * @see udp_disconnect() udp_send() 00533 */ 00534 err_t 00535 udp_sendto(struct udp_pcb *pcb, struct pbuf *p, 00536 const ip_addr_t *dst_ip, u16_t dst_port) 00537 { 00538 #if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP 00539 return udp_sendto_chksum(pcb, p, dst_ip, dst_port, 0, 0); 00540 } 00541 00542 /** @ingroup udp_raw 00543 * Same as udp_sendto(), but with checksum */ 00544 err_t 00545 udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, 00546 u16_t dst_port, u8_t have_chksum, u16_t chksum) 00547 { 00548 #endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ 00549 struct netif *netif; 00550 const ip_addr_t *dst_ip_route = dst_ip; 00551 00552 if ((pcb == NULL) || (dst_ip == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) { 00553 return ERR_VAL; 00554 } 00555 00556 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n")); 00557 00558 #if LWIP_IPV6 || (LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS) 00559 if (ip_addr_ismulticast(dst_ip_route)) { 00560 #if LWIP_IPV6 00561 if (IP_IS_V6(dst_ip)) { 00562 /* For multicast, find a netif based on source address. */ 00563 dst_ip_route = &pcb->local_ip; 00564 } else 00565 #endif /* LWIP_IPV6 */ 00566 { 00567 #if LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS 00568 /* IPv4 does not use source-based routing by default, so we use an 00569 administratively selected interface for multicast by default. 00570 However, this can be overridden by setting an interface address 00571 in pcb->multicast_ip that is used for routing. */ 00572 if (!ip_addr_isany_val(pcb->multicast_ip) && 00573 !ip4_addr_cmp(ip_2_ip4(&pcb->multicast_ip), IP4_ADDR_BROADCAST)) { 00574 dst_ip_route = &pcb->multicast_ip; 00575 } 00576 #endif /* LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS */ 00577 } 00578 } 00579 #endif /* LWIP_IPV6 || (LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS) */ 00580 00581 /* find the outgoing network interface for this packet */ 00582 netif = ip_route(&pcb->local_ip, dst_ip_route); 00583 00584 /* no outgoing network interface could be found? */ 00585 if (netif == NULL) { 00586 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to ")); 00587 ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, dst_ip); 00588 LWIP_DEBUGF(UDP_DEBUG, ("\n")); 00589 UDP_STATS_INC(udp.rterr); 00590 return ERR_RTE; 00591 } 00592 #if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP 00593 return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum); 00594 #else /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ 00595 return udp_sendto_if(pcb, p, dst_ip, dst_port, netif); 00596 #endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ 00597 } 00598 00599 /** 00600 * @ingroup udp_raw 00601 * Send data to a specified address using UDP. 00602 * The netif used for sending can be specified. 00603 * 00604 * This function exists mainly for DHCP, to be able to send UDP packets 00605 * on a netif that is still down. 00606 * 00607 * @param pcb UDP PCB used to send the data. 00608 * @param p chain of pbuf's to be sent. 00609 * @param dst_ip Destination IP address. 00610 * @param dst_port Destination UDP port. 00611 * @param netif the netif used for sending. 00612 * 00613 * dst_ip & dst_port are expected to be in the same byte order as in the pcb. 00614 * 00615 * @return lwIP error code (@see udp_send for possible error codes) 00616 * 00617 * @see udp_disconnect() udp_send() 00618 */ 00619 err_t 00620 udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p, 00621 const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif) 00622 { 00623 #if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP 00624 return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, 0, 0); 00625 } 00626 00627 /** Same as udp_sendto_if(), but with checksum */ 00628 err_t 00629 udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, 00630 u16_t dst_port, struct netif *netif, u8_t have_chksum, 00631 u16_t chksum) 00632 { 00633 #endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ 00634 const ip_addr_t *src_ip; 00635 00636 if ((pcb == NULL) || (dst_ip == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) { 00637 return ERR_VAL; 00638 } 00639 00640 /* PCB local address is IP_ANY_ADDR? */ 00641 #if LWIP_IPV6 00642 if (IP_IS_V6(dst_ip)) { 00643 if (ip6_addr_isany(ip_2_ip6(&pcb->local_ip))) { 00644 src_ip = ip6_select_source_address(netif, ip_2_ip6(dst_ip)); 00645 if (src_ip == NULL) { 00646 /* No suitable source address was found. */ 00647 return ERR_RTE; 00648 } 00649 } else { 00650 /* use UDP PCB local IPv6 address as source address, if still valid. */ 00651 if (netif_get_ip6_addr_match(netif, ip_2_ip6(&pcb->local_ip)) < 0) { 00652 /* Address isn't valid anymore. */ 00653 return ERR_RTE; 00654 } 00655 src_ip = &pcb->local_ip; 00656 } 00657 } 00658 #endif /* LWIP_IPV6 */ 00659 #if LWIP_IPV4 && LWIP_IPV6 00660 else 00661 #endif /* LWIP_IPV4 && LWIP_IPV6 */ 00662 #if LWIP_IPV4 00663 if (ip4_addr_isany(ip_2_ip4(&pcb->local_ip)) || 00664 ip4_addr_ismulticast(ip_2_ip4(&pcb->local_ip))) { 00665 /* if the local_ip is any or multicast 00666 * use the outgoing network interface IP address as source address */ 00667 src_ip = netif_ip_addr4(netif); 00668 } else { 00669 /* check if UDP PCB local IP address is correct 00670 * this could be an old address if netif->ip_addr has changed */ 00671 if (!ip4_addr_cmp(ip_2_ip4(&(pcb->local_ip)), netif_ip4_addr(netif))) { 00672 /* local_ip doesn't match, drop the packet */ 00673 return ERR_VAL; 00674 } 00675 /* use UDP PCB local IP address as source address */ 00676 src_ip = &pcb->local_ip; 00677 } 00678 #endif /* LWIP_IPV4 */ 00679 #if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP 00680 return udp_sendto_if_src_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum, src_ip); 00681 #else /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ 00682 return udp_sendto_if_src(pcb, p, dst_ip, dst_port, netif, src_ip); 00683 #endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ 00684 } 00685 00686 /** @ingroup udp_raw 00687 * Same as @ref udp_sendto_if, but with source address */ 00688 err_t 00689 udp_sendto_if_src(struct udp_pcb *pcb, struct pbuf *p, 00690 const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif, const ip_addr_t *src_ip) 00691 { 00692 #if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP 00693 return udp_sendto_if_src_chksum(pcb, p, dst_ip, dst_port, netif, 0, 0, src_ip); 00694 } 00695 00696 /** Same as udp_sendto_if_src(), but with checksum */ 00697 err_t 00698 udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, 00699 u16_t dst_port, struct netif *netif, u8_t have_chksum, 00700 u16_t chksum, const ip_addr_t *src_ip) 00701 { 00702 #endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ 00703 struct udp_hdr *udphdr; 00704 err_t err; 00705 struct pbuf *q; /* q will be sent down the stack */ 00706 u8_t ip_proto; 00707 u8_t ttl; 00708 00709 if ((pcb == NULL) || (dst_ip == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, src_ip) || 00710 !IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) { 00711 return ERR_VAL; 00712 } 00713 00714 #if LWIP_IPV4 && IP_SOF_BROADCAST 00715 /* broadcast filter? */ 00716 if (!ip_get_option(pcb, SOF_BROADCAST) && 00717 #if LWIP_IPV6 00718 IP_IS_V4(dst_ip) && 00719 #endif /* LWIP_IPV6 */ 00720 ip_addr_isbroadcast(dst_ip, netif)) { 00721 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, 00722 ("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); 00723 return ERR_VAL; 00724 } 00725 #endif /* LWIP_IPV4 && IP_SOF_BROADCAST */ 00726 00727 /* if the PCB is not yet bound to a port, bind it here */ 00728 if (pcb->local_port == 0) { 00729 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n")); 00730 err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); 00731 if (err != ERR_OK) { 00732 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n")); 00733 return err; 00734 } 00735 } 00736 00737 /* not enough space to add an UDP header to first pbuf in given p chain? */ 00738 if (pbuf_header(p, UDP_HLEN)) { 00739 /* allocate header in a separate new pbuf */ 00740 q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM); 00741 /* new header pbuf could not be allocated? */ 00742 if (q == NULL) { 00743 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n")); 00744 return ERR_MEM; 00745 } 00746 if (p->tot_len != 0) { 00747 /* chain header q in front of given pbuf p (only if p contains data) */ 00748 pbuf_chain(q, p); 00749 } 00750 /* first pbuf q points to header pbuf */ 00751 LWIP_DEBUGF(UDP_DEBUG, 00752 ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); 00753 } else { 00754 /* adding space for header within p succeeded */ 00755 /* first pbuf q equals given pbuf */ 00756 q = p; 00757 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p)); 00758 } 00759 LWIP_ASSERT("check that first pbuf can hold struct udp_hdr", 00760 (q->len >= sizeof(struct udp_hdr))); 00761 /* q now represents the packet to be sent */ 00762 udphdr = (struct udp_hdr *)q->payload; 00763 udphdr->src = htons(pcb->local_port); 00764 udphdr->dest = htons(dst_port); 00765 /* in UDP, 0 checksum means 'no checksum' */ 00766 udphdr->chksum = 0x0000; 00767 00768 /* Multicast Loop? */ 00769 #if (LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS) || (LWIP_IPV6 && LWIP_IPV6_MLD) 00770 if (((pcb->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) && ip_addr_ismulticast(dst_ip)) { 00771 q->flags |= PBUF_FLAG_MCASTLOOP; 00772 } 00773 #endif /* (LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS) || (LWIP_IPV6 && LWIP_IPV6_MLD) */ 00774 00775 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len)); 00776 00777 #if LWIP_UDPLITE 00778 /* UDP Lite protocol? */ 00779 if (pcb->flags & UDP_FLAGS_UDPLITE) { 00780 u16_t chklen, chklen_hdr; 00781 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len)); 00782 /* set UDP message length in UDP header */ 00783 chklen_hdr = chklen = pcb->chksum_len_tx; 00784 if ((chklen < sizeof(struct udp_hdr)) || (chklen > q->tot_len)) { 00785 if (chklen != 0) { 00786 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE pcb->chksum_len is illegal: %"U16_F"\n", chklen)); 00787 } 00788 /* For UDP-Lite, checksum length of 0 means checksum 00789 over the complete packet. (See RFC 3828 chap. 3.1) 00790 At least the UDP-Lite header must be covered by the 00791 checksum, therefore, if chksum_len has an illegal 00792 value, we generate the checksum over the complete 00793 packet to be safe. */ 00794 chklen_hdr = 0; 00795 chklen = q->tot_len; 00796 } 00797 udphdr->len = htons(chklen_hdr); 00798 /* calculate checksum */ 00799 #if CHECKSUM_GEN_UDP 00800 IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_UDP) { 00801 #if LWIP_CHECKSUM_ON_COPY 00802 if (have_chksum) { 00803 chklen = UDP_HLEN; 00804 } 00805 #endif /* LWIP_CHECKSUM_ON_COPY */ 00806 udphdr->chksum = ip_chksum_pseudo_partial(q, IP_PROTO_UDPLITE, 00807 q->tot_len, chklen, src_ip, dst_ip); 00808 #if LWIP_CHECKSUM_ON_COPY 00809 if (have_chksum) { 00810 u32_t acc; 00811 acc = udphdr->chksum + (u16_t)~(chksum); 00812 udphdr->chksum = FOLD_U32T(acc); 00813 } 00814 #endif /* LWIP_CHECKSUM_ON_COPY */ 00815 00816 /* chksum zero must become 0xffff, as zero means 'no checksum' */ 00817 if (udphdr->chksum == 0x0000) { 00818 udphdr->chksum = 0xffff; 00819 } 00820 } 00821 #endif /* CHECKSUM_GEN_UDP */ 00822 00823 ip_proto = IP_PROTO_UDPLITE; 00824 } else 00825 #endif /* LWIP_UDPLITE */ 00826 { /* UDP */ 00827 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len)); 00828 udphdr->len = htons(q->tot_len); 00829 /* calculate checksum */ 00830 #if CHECKSUM_GEN_UDP 00831 IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_UDP) { 00832 /* Checksum is mandatory over IPv6. */ 00833 if (IP_IS_V6(dst_ip) || (pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { 00834 u16_t udpchksum; 00835 #if LWIP_CHECKSUM_ON_COPY 00836 if (have_chksum) { 00837 u32_t acc; 00838 udpchksum = ip_chksum_pseudo_partial(q, IP_PROTO_UDP, 00839 q->tot_len, UDP_HLEN, src_ip, dst_ip); 00840 acc = udpchksum + (u16_t)~(chksum); 00841 udpchksum = FOLD_U32T(acc); 00842 } else 00843 #endif /* LWIP_CHECKSUM_ON_COPY */ 00844 { 00845 udpchksum = ip_chksum_pseudo(q, IP_PROTO_UDP, q->tot_len, 00846 src_ip, dst_ip); 00847 } 00848 00849 /* chksum zero must become 0xffff, as zero means 'no checksum' */ 00850 if (udpchksum == 0x0000) { 00851 udpchksum = 0xffff; 00852 } 00853 udphdr->chksum = udpchksum; 00854 } 00855 } 00856 #endif /* CHECKSUM_GEN_UDP */ 00857 ip_proto = IP_PROTO_UDP; 00858 } 00859 00860 /* Determine TTL to use */ 00861 #if LWIP_MULTICAST_TX_OPTIONS 00862 ttl = (ip_addr_ismulticast(dst_ip) ? pcb->mcast_ttl : pcb->ttl); 00863 #else /* LWIP_MULTICAST_TX_OPTIONS */ 00864 ttl = pcb->ttl; 00865 #endif /* LWIP_MULTICAST_TX_OPTIONS */ 00866 00867 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum)); 00868 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,0x%02"X16_F",)\n", (u16_t)ip_proto)); 00869 /* output to IP */ 00870 NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint)); 00871 err = ip_output_if_src(q, src_ip, dst_ip, ttl, pcb->tos, ip_proto, netif); 00872 NETIF_SET_HWADDRHINT(netif, NULL); 00873 00874 /* @todo: must this be increased even if error occurred? */ 00875 MIB2_STATS_INC(mib2.udpoutdatagrams); 00876 00877 /* did we chain a separate header pbuf earlier? */ 00878 if (q != p) { 00879 /* free the header pbuf */ 00880 pbuf_free(q); 00881 q = NULL; 00882 /* p is still referenced by the caller, and will live on */ 00883 } 00884 00885 UDP_STATS_INC(udp.xmit); 00886 return err; 00887 } 00888 00889 /** 00890 * @ingroup udp_raw 00891 * Bind an UDP PCB. 00892 * 00893 * @param pcb UDP PCB to be bound with a local address ipaddr and port. 00894 * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to 00895 * bind to all local interfaces. 00896 * @param port local UDP port to bind with. Use 0 to automatically bind 00897 * to a random port between UDP_LOCAL_PORT_RANGE_START and 00898 * UDP_LOCAL_PORT_RANGE_END. 00899 * 00900 * ipaddr & port are expected to be in the same byte order as in the pcb. 00901 * 00902 * @return lwIP error code. 00903 * - ERR_OK. Successful. No error occurred. 00904 * - ERR_USE. The specified ipaddr and port are already bound to by 00905 * another UDP PCB. 00906 * 00907 * @see udp_disconnect() 00908 */ 00909 err_t 00910 udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port) 00911 { 00912 struct udp_pcb *ipcb; 00913 u8_t rebind; 00914 00915 #if LWIP_IPV4 00916 /* Don't propagate NULL pointer (IPv4 ANY) to subsequent functions */ 00917 if (ipaddr == NULL) { 00918 ipaddr = IP_ADDR_ANY; 00919 } 00920 #endif /* LWIP_IPV4 */ 00921 00922 /* still need to check for ipaddr == NULL in IPv6 only case */ 00923 if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr)) { 00924 return ERR_VAL; 00925 } 00926 00927 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = ")); 00928 ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE, ipaddr); 00929 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port)); 00930 00931 rebind = 0; 00932 /* Check for double bind and rebind of the same pcb */ 00933 for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { 00934 /* is this UDP PCB already on active list? */ 00935 if (pcb == ipcb) { 00936 rebind = 1; 00937 break; 00938 } 00939 } 00940 00941 /* no port specified? */ 00942 if (port == 0) { 00943 port = udp_new_port(); 00944 if (port == 0) { 00945 /* no more ports available in local range */ 00946 LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n")); 00947 return ERR_USE; 00948 } 00949 } else { 00950 for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { 00951 if (pcb != ipcb) { 00952 /* By default, we don't allow to bind to a port that any other udp 00953 PCB is already bound to, unless *all* PCBs with that port have tha 00954 REUSEADDR flag set. */ 00955 #if SO_REUSE 00956 if (!ip_get_option(pcb, SOF_REUSEADDR) || 00957 !ip_get_option(ipcb, SOF_REUSEADDR)) 00958 #endif /* SO_REUSE */ 00959 { 00960 /* port matches that of PCB in list and REUSEADDR not set -> reject */ 00961 if ((ipcb->local_port == port) && 00962 /* IP address matches? */ 00963 ip_addr_cmp(&ipcb->local_ip, ipaddr)) { 00964 /* other PCB already binds to this local IP and port */ 00965 LWIP_DEBUGF(UDP_DEBUG, 00966 ("udp_bind: local port %"U16_F" already bound by another pcb\n", port)); 00967 return ERR_USE; 00968 } 00969 } 00970 } 00971 } 00972 } 00973 00974 ip_addr_set_ipaddr(&pcb->local_ip, ipaddr); 00975 00976 pcb->local_port = port; 00977 mib2_udp_bind(pcb); 00978 /* pcb not active yet? */ 00979 if (rebind == 0) { 00980 /* place the PCB on the active list if not already there */ 00981 pcb->next = udp_pcbs; 00982 udp_pcbs = pcb; 00983 } 00984 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_bind: bound to ")); 00985 ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, &pcb->local_ip); 00986 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->local_port)); 00987 return ERR_OK; 00988 } 00989 00990 /** 00991 * @ingroup udp_raw 00992 * Connect an UDP PCB. 00993 * 00994 * This will associate the UDP PCB with the remote address. 00995 * 00996 * @param pcb UDP PCB to be connected with remote address ipaddr and port. 00997 * @param ipaddr remote IP address to connect with. 00998 * @param port remote UDP port to connect with. 00999 * 01000 * @return lwIP error code 01001 * 01002 * ipaddr & port are expected to be in the same byte order as in the pcb. 01003 * 01004 * The udp pcb is bound to a random local port if not already bound. 01005 * 01006 * @see udp_disconnect() 01007 */ 01008 err_t 01009 udp_connect(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port) 01010 { 01011 struct udp_pcb *ipcb; 01012 01013 if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) { 01014 return ERR_VAL; 01015 } 01016 01017 if (pcb->local_port == 0) { 01018 err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); 01019 if (err != ERR_OK) { 01020 return err; 01021 } 01022 } 01023 01024 ip_addr_set_ipaddr(&pcb->remote_ip, ipaddr); 01025 pcb->remote_port = port; 01026 pcb->flags |= UDP_FLAGS_CONNECTED; 01027 01028 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_connect: connected to ")); 01029 ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, 01030 &pcb->remote_ip); 01031 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->remote_port)); 01032 01033 /* Insert UDP PCB into the list of active UDP PCBs. */ 01034 for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { 01035 if (pcb == ipcb) { 01036 /* already on the list, just return */ 01037 return ERR_OK; 01038 } 01039 } 01040 /* PCB not yet on the list, add PCB now */ 01041 pcb->next = udp_pcbs; 01042 udp_pcbs = pcb; 01043 return ERR_OK; 01044 } 01045 01046 /** 01047 * @ingroup udp_raw 01048 * Disconnect a UDP PCB 01049 * 01050 * @param pcb the udp pcb to disconnect. 01051 */ 01052 void 01053 udp_disconnect(struct udp_pcb *pcb) 01054 { 01055 /* reset remote address association */ 01056 #if LWIP_IPV4 && LWIP_IPV6 01057 if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) { 01058 ip_addr_copy(pcb->remote_ip, *IP_ANY_TYPE); 01059 } else { 01060 #endif 01061 ip_addr_set_any(IP_IS_V6_VAL(pcb->remote_ip), &pcb->remote_ip); 01062 #if LWIP_IPV4 && LWIP_IPV6 01063 } 01064 #endif 01065 pcb->remote_port = 0; 01066 /* mark PCB as unconnected */ 01067 pcb->flags &= ~UDP_FLAGS_CONNECTED; 01068 } 01069 01070 /** 01071 * @ingroup udp_raw 01072 * Set a receive callback for a UDP PCB 01073 * 01074 * This callback will be called when receiving a datagram for the pcb. 01075 * 01076 * @param pcb the pcb for which to set the recv callback 01077 * @param recv function pointer of the callback function 01078 * @param recv_arg additional argument to pass to the callback function 01079 */ 01080 void 01081 udp_recv(struct udp_pcb *pcb, udp_recv_fn recv, void *recv_arg) 01082 { 01083 /* remember recv() callback and user data */ 01084 pcb->recv = recv; 01085 pcb->recv_arg = recv_arg; 01086 } 01087 01088 /** 01089 * @ingroup udp_raw 01090 * Remove an UDP PCB. 01091 * 01092 * @param pcb UDP PCB to be removed. The PCB is removed from the list of 01093 * UDP PCB's and the data structure is freed from memory. 01094 * 01095 * @see udp_new() 01096 */ 01097 void 01098 udp_remove(struct udp_pcb *pcb) 01099 { 01100 struct udp_pcb *pcb2; 01101 01102 mib2_udp_unbind(pcb); 01103 /* pcb to be removed is first in list? */ 01104 if (udp_pcbs == pcb) { 01105 /* make list start at 2nd pcb */ 01106 udp_pcbs = udp_pcbs->next; 01107 /* pcb not 1st in list */ 01108 } else { 01109 for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { 01110 /* find pcb in udp_pcbs list */ 01111 if (pcb2->next != NULL && pcb2->next == pcb) { 01112 /* remove pcb from list */ 01113 pcb2->next = pcb->next; 01114 break; 01115 } 01116 } 01117 } 01118 memp_free(MEMP_UDP_PCB, pcb); 01119 } 01120 01121 /** 01122 * @ingroup udp_raw 01123 * Create a UDP PCB. 01124 * 01125 * @return The UDP PCB which was created. NULL if the PCB data structure 01126 * could not be allocated. 01127 * 01128 * @see udp_remove() 01129 */ 01130 struct udp_pcb * 01131 udp_new(void) 01132 { 01133 struct udp_pcb *pcb; 01134 pcb = (struct udp_pcb *)memp_malloc(MEMP_UDP_PCB); 01135 /* could allocate UDP PCB? */ 01136 if (pcb != NULL) { 01137 /* UDP Lite: by initializing to all zeroes, chksum_len is set to 0 01138 * which means checksum is generated over the whole datagram per default 01139 * (recommended as default by RFC 3828). */ 01140 /* initialize PCB to all zeroes */ 01141 memset(pcb, 0, sizeof(struct udp_pcb)); 01142 pcb->ttl = UDP_TTL; 01143 #if LWIP_MULTICAST_TX_OPTIONS 01144 pcb->mcast_ttl = UDP_TTL; 01145 #endif /* LWIP_MULTICAST_TX_OPTIONS */ 01146 } 01147 return pcb; 01148 } 01149 01150 /** 01151 * @ingroup udp_raw 01152 * Create a UDP PCB for specific IP type. 01153 * 01154 * @param type IP address type, see IPADDR_TYPE_XX definitions. 01155 * @return The UDP PCB which was created. NULL if the PCB data structure 01156 * could not be allocated. 01157 * 01158 * @see udp_remove() 01159 */ 01160 struct udp_pcb * 01161 udp_new_ip_type(u8_t type) 01162 { 01163 struct udp_pcb *pcb; 01164 pcb = udp_new(); 01165 #if LWIP_IPV4 && LWIP_IPV6 01166 if (pcb != NULL) { 01167 IP_SET_TYPE_VAL(pcb->local_ip, type); 01168 IP_SET_TYPE_VAL(pcb->remote_ip, type); 01169 } 01170 #else 01171 LWIP_UNUSED_ARG(type); 01172 #endif /* LWIP_IPV4 && LWIP_IPV6 */ 01173 return pcb; 01174 } 01175 01176 #if LWIP_IPV4 01177 /** This function is called from netif.c when address is changed 01178 * 01179 * @param old_addr IPv4 address of the netif before change 01180 * @param new_addr IPv4 address of the netif after change 01181 */ 01182 void udp_netif_ipv4_addr_changed(const ip4_addr_t* old_addr, const ip4_addr_t* new_addr) 01183 { 01184 struct udp_pcb* upcb; 01185 01186 if (!ip4_addr_isany(new_addr)) { 01187 for (upcb = udp_pcbs; upcb != NULL; upcb = upcb->next) { 01188 /* Is this an IPv4 pcb? */ 01189 if (IP_IS_V4_VAL(upcb->local_ip)) { 01190 /* PCB bound to current local interface address? */ 01191 if (!ip4_addr_isany(ip_2_ip4(&upcb->local_ip)) && 01192 ip4_addr_cmp(ip_2_ip4(&upcb->local_ip), old_addr)) { 01193 /* The PCB is bound to the old ipaddr and 01194 * is set to bound to the new one instead */ 01195 ip_addr_copy_from_ip4(upcb->local_ip, *new_addr); 01196 } 01197 } 01198 } 01199 } 01200 } 01201 #endif /* LWIP_IPV4 */ 01202 01203 #if UDP_DEBUG 01204 /** 01205 * Print UDP header information for debug purposes. 01206 * 01207 * @param udphdr pointer to the udp header in memory. 01208 */ 01209 void 01210 udp_debug_print(struct udp_hdr *udphdr) 01211 { 01212 LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n")); 01213 LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); 01214 LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", 01215 ntohs(udphdr->src), ntohs(udphdr->dest))); 01216 LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); 01217 LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | 0x%04"X16_F" | (len, chksum)\n", 01218 ntohs(udphdr->len), ntohs(udphdr->chksum))); 01219 LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); 01220 } 01221 #endif /* UDP_DEBUG */ 01222 01223 #endif /* LWIP_UDP */
Generated on Tue Jul 12 2022 13:15:55 by
