00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include "lwip/opt.h"
00050
00051 #if LWIP_UDP
00052
00053 #include "lwip/udp.h"
00054 #include "lwip/def.h"
00055 #include "lwip/memp.h"
00056 #include "lwip/inet.h"
00057 #include "lwip/inet_chksum.h"
00058 #include "lwip/ip_addr.h"
00059 #include "lwip/netif.h"
00060 #include "lwip/icmp.h"
00061 #include "lwip/stats.h"
00062 #include "lwip/snmp.h"
00063 #include "arch/perf.h"
00064 #include "lwip/dhcp.h"
00065
00066 #include <string.h>
00067
00068
00069
00070 struct udp_pcb *udp_pcbs;
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 void
00085 udp_input(struct pbuf *p, struct netif *inp)
00086 {
00087 struct udp_hdr *udphdr;
00088 struct udp_pcb *pcb, *prev;
00089 struct udp_pcb *uncon_pcb;
00090 struct ip_hdr *iphdr;
00091 u16_t src, dest;
00092 u8_t local_match;
00093 u8_t broadcast;
00094
00095 PERF_START;
00096
00097 UDP_STATS_INC(udp.recv);
00098
00099 iphdr = p->payload;
00100
00101
00102
00103 if (p->tot_len < (IPH_HL(iphdr) * 4 + UDP_HLEN) || pbuf_header(p, -(s16_t)(IPH_HL(iphdr) * 4))) {
00104
00105 LWIP_DEBUGF(UDP_DEBUG,
00106 ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len));
00107 UDP_STATS_INC(udp.lenerr);
00108 UDP_STATS_INC(udp.drop);
00109 snmp_inc_udpinerrors();
00110 pbuf_free(p);
00111 goto end;
00112 }
00113
00114 udphdr = (struct udp_hdr *)p->payload;
00115
00116
00117 broadcast = ip_addr_isbroadcast(&(iphdr->dest), inp);
00118
00119 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len));
00120
00121
00122 src = ntohs(udphdr->src);
00123 dest = ntohs(udphdr->dest);
00124
00125 udp_debug_print(udphdr);
00126
00127
00128 LWIP_DEBUGF(UDP_DEBUG,
00129 ("udp (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") <-- "
00130 "(%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n",
00131 ip4_addr1(&iphdr->dest), ip4_addr2(&iphdr->dest),
00132 ip4_addr3(&iphdr->dest), ip4_addr4(&iphdr->dest), ntohs(udphdr->dest),
00133 ip4_addr1(&iphdr->src), ip4_addr2(&iphdr->src),
00134 ip4_addr3(&iphdr->src), ip4_addr4(&iphdr->src), ntohs(udphdr->src)));
00135
00136 #if LWIP_DHCP
00137 pcb = NULL;
00138
00139
00140 if (dest == DHCP_CLIENT_PORT) {
00141
00142 if (src == DHCP_SERVER_PORT) {
00143 if ((inp->dhcp != NULL) && (inp->dhcp->pcb != NULL)) {
00144
00145
00146
00147 if ((ip_addr_isany(&inp->dhcp->pcb->remote_ip) ||
00148 ip_addr_cmp(&(inp->dhcp->pcb->remote_ip), &(iphdr->src)))) {
00149 pcb = inp->dhcp->pcb;
00150 }
00151 }
00152 }
00153 } else
00154 #endif
00155 {
00156 prev = NULL;
00157 local_match = 0;
00158 uncon_pcb = NULL;
00159
00160
00161
00162
00163 for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
00164 local_match = 0;
00165
00166 LWIP_DEBUGF(UDP_DEBUG,
00167 ("pcb (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") --- "
00168 "(%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n",
00169 ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip),
00170 ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port,
00171 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
00172 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));
00173
00174
00175 if ((pcb->local_port == dest) &&
00176 ((!broadcast && ip_addr_isany(&pcb->local_ip)) ||
00177 ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)) ||
00178 #if LWIP_IGMP
00179 ip_addr_ismulticast(&(iphdr->dest)) ||
00180 #endif
00181 #if IP_SOF_BROADCAST_RECV
00182 (broadcast && (pcb->so_options & SOF_BROADCAST)))) {
00183 #else
00184 (broadcast))) {
00185 #endif
00186 local_match = 1;
00187 if ((uncon_pcb == NULL) &&
00188 ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) {
00189
00190 uncon_pcb = pcb;
00191 }
00192 }
00193
00194 if ((local_match != 0) &&
00195 (pcb->remote_port == src) &&
00196 (ip_addr_isany(&pcb->remote_ip) ||
00197 ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)))) {
00198
00199 if (prev != NULL) {
00200
00201
00202 prev->next = pcb->next;
00203 pcb->next = udp_pcbs;
00204 udp_pcbs = pcb;
00205 } else {
00206 UDP_STATS_INC(udp.cachehit);
00207 }
00208 break;
00209 }
00210 prev = pcb;
00211 }
00212
00213 if (pcb == NULL) {
00214 pcb = uncon_pcb;
00215 }
00216 }
00217
00218
00219 if (pcb != NULL || ip_addr_cmp(&inp->ip_addr, &iphdr->dest)) {
00220 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n"));
00221 #if LWIP_UDPLITE
00222 if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
00223
00224 #if CHECKSUM_CHECK_UDP
00225 u16_t chklen = ntohs(udphdr->len);
00226 if (chklen < sizeof(struct udp_hdr)) {
00227 if (chklen == 0) {
00228
00229
00230 chklen = p->tot_len;
00231 } else {
00232
00233
00234 UDP_STATS_INC(udp.chkerr);
00235 UDP_STATS_INC(udp.drop);
00236 snmp_inc_udpinerrors();
00237 pbuf_free(p);
00238 goto end;
00239 }
00240 }
00241 if (inet_chksum_pseudo_partial(p, (struct ip_addr *)&(iphdr->src),
00242 (struct ip_addr *)&(iphdr->dest),
00243 IP_PROTO_UDPLITE, p->tot_len, chklen) != 0) {
00244 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
00245 ("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
00246 UDP_STATS_INC(udp.chkerr);
00247 UDP_STATS_INC(udp.drop);
00248 snmp_inc_udpinerrors();
00249 pbuf_free(p);
00250 goto end;
00251 }
00252 #endif
00253 } else
00254 #endif
00255 {
00256 #if CHECKSUM_CHECK_UDP
00257 if (udphdr->chksum != 0) {
00258 if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
00259 (struct ip_addr *)&(iphdr->dest),
00260 IP_PROTO_UDP, p->tot_len) != 0) {
00261 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
00262 ("udp_input: UDP datagram discarded due to failing checksum\n"));
00263 UDP_STATS_INC(udp.chkerr);
00264 UDP_STATS_INC(udp.drop);
00265 snmp_inc_udpinerrors();
00266 pbuf_free(p);
00267 goto end;
00268 }
00269 }
00270 #endif
00271 }
00272 if(pbuf_header(p, -UDP_HLEN)) {
00273
00274 LWIP_ASSERT("pbuf_header failed\n", 0);
00275 UDP_STATS_INC(udp.drop);
00276 snmp_inc_udpinerrors();
00277 pbuf_free(p);
00278 goto end;
00279 }
00280 if (pcb != NULL) {
00281 snmp_inc_udpindatagrams();
00282
00283 if (pcb->recv != NULL) {
00284
00285 pcb->recv(pcb->recv_arg, pcb, p, &iphdr->src, src);
00286 } else {
00287
00288 pbuf_free(p);
00289 goto end;
00290 }
00291 } else {
00292 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: not for us.\n"));
00293
00294 #if LWIP_ICMP
00295
00296
00297 if (!broadcast &&
00298 !ip_addr_ismulticast(&iphdr->dest)) {
00299
00300 pbuf_header(p, (IPH_HL(iphdr) * 4) + UDP_HLEN);
00301 LWIP_ASSERT("p->payload == iphdr", (p->payload == iphdr));
00302 icmp_dest_unreach(p, ICMP_DUR_PORT);
00303 }
00304 #endif
00305 UDP_STATS_INC(udp.proterr);
00306 UDP_STATS_INC(udp.drop);
00307 snmp_inc_udpnoports();
00308 pbuf_free(p);
00309 }
00310 } else {
00311 pbuf_free(p);
00312 }
00313 end:
00314 PERF_STOP("udp_input");
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 err_t
00336 udp_send(struct udp_pcb *pcb, struct pbuf *p)
00337 {
00338
00339 return udp_sendto(pcb, p, &pcb->remote_ip, pcb->remote_port);
00340 }
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 err_t
00360 udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
00361 struct ip_addr *dst_ip, u16_t dst_port)
00362 {
00363 struct netif *netif;
00364
00365 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n"));
00366
00367
00368 #if LWIP_IGMP
00369 netif = ip_route((ip_addr_ismulticast(dst_ip))?(&(pcb->multicast_ip)):(dst_ip));
00370 #else
00371 netif = ip_route(dst_ip);
00372 #endif
00373
00374
00375 if (netif == NULL) {
00376 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to 0x%"X32_F"\n", dst_ip->addr));
00377 UDP_STATS_INC(udp.rterr);
00378 return ERR_RTE;
00379 }
00380 return udp_sendto_if(pcb, p, dst_ip, dst_port, netif);
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 err_t
00403 udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p,
00404 struct ip_addr *dst_ip, u16_t dst_port, struct netif *netif)
00405 {
00406 struct udp_hdr *udphdr;
00407 struct ip_addr *src_ip;
00408 err_t err;
00409 struct pbuf *q;
00410
00411 #if IP_SOF_BROADCAST
00412
00413 if ( ((pcb->so_options & SOF_BROADCAST) == 0) && ip_addr_isbroadcast(dst_ip, netif) ) {
00414 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
00415 ("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
00416 return ERR_VAL;
00417 }
00418 #endif
00419
00420
00421 if (pcb->local_port == 0) {
00422 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n"));
00423 err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
00424 if (err != ERR_OK) {
00425 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n"));
00426 return err;
00427 }
00428 }
00429
00430
00431 if (pbuf_header(p, UDP_HLEN)) {
00432
00433 q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);
00434
00435 if (q == NULL) {
00436 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n"));
00437 return ERR_MEM;
00438 }
00439
00440 pbuf_chain(q, p);
00441
00442 LWIP_DEBUGF(UDP_DEBUG,
00443 ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
00444 } else {
00445
00446
00447 q = p;
00448 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));
00449 }
00450 LWIP_ASSERT("check that first pbuf can hold struct udp_hdr",
00451 (q->len >= sizeof(struct udp_hdr)));
00452
00453 udphdr = q->payload;
00454 udphdr->src = htons(pcb->local_port);
00455 udphdr->dest = htons(dst_port);
00456
00457 udphdr->chksum = 0x0000;
00458
00459
00460 if (ip_addr_isany(&pcb->local_ip)) {
00461
00462 src_ip = &(netif->ip_addr);
00463 } else {
00464
00465
00466 if (!ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {
00467
00468 if (q != p) {
00469
00470 pbuf_free(q);
00471 q = NULL;
00472
00473 }
00474 return ERR_VAL;
00475 }
00476
00477 src_ip = &(pcb->local_ip);
00478 }
00479
00480 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len));
00481
00482 #if LWIP_UDPLITE
00483
00484 if (pcb->flags & UDP_FLAGS_UDPLITE) {
00485 u16_t chklen, chklen_hdr;
00486 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len));
00487
00488 chklen_hdr = chklen = pcb->chksum_len_tx;
00489 if ((chklen < sizeof(struct udp_hdr)) || (chklen > q->tot_len)) {
00490 if (chklen != 0) {
00491 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE pcb->chksum_len is illegal: %"U16_F"\n", chklen));
00492 }
00493
00494
00495
00496
00497
00498
00499 chklen_hdr = 0;
00500 chklen = q->tot_len;
00501 }
00502 udphdr->len = htons(chklen_hdr);
00503
00504 #if CHECKSUM_GEN_UDP
00505 udphdr->chksum = inet_chksum_pseudo_partial(q, src_ip, dst_ip,
00506 IP_PROTO_UDPLITE, q->tot_len, chklen);
00507
00508 if (udphdr->chksum == 0x0000)
00509 udphdr->chksum = 0xffff;
00510 #endif
00511
00512 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));
00513 #if LWIP_NETIF_HWADDRHINT
00514 netif->addr_hint = &(pcb->addr_hint);
00515 #endif
00516 err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);
00517 #if LWIP_NETIF_HWADDRHINT
00518 netif->addr_hint = NULL;
00519 #endif
00520 } else
00521 #endif
00522 {
00523 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len));
00524 udphdr->len = htons(q->tot_len);
00525
00526 #if CHECKSUM_GEN_UDP
00527 if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
00528 udphdr->chksum = inet_chksum_pseudo(q, src_ip, dst_ip, IP_PROTO_UDP, q->tot_len);
00529
00530 if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
00531 }
00532 #endif
00533 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum));
00534 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
00535
00536 #if LWIP_NETIF_HWADDRHINT
00537 netif->addr_hint = &(pcb->addr_hint);
00538 #endif
00539 err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);
00540 #if LWIP_NETIF_HWADDRHINT
00541 netif->addr_hint = NULL;
00542 #endif
00543 }
00544
00545 snmp_inc_udpoutdatagrams();
00546
00547
00548 if (q != p) {
00549
00550 pbuf_free(q);
00551 q = NULL;
00552
00553 }
00554
00555 UDP_STATS_INC(udp.xmit);
00556 return err;
00557 }
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 err_t
00579 udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
00580 {
00581 struct udp_pcb *ipcb;
00582 u8_t rebind;
00583
00584 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = "));
00585 ip_addr_debug_print(UDP_DEBUG, ipaddr);
00586 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port));
00587
00588 rebind = 0;
00589
00590 for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
00591
00592 if (pcb == ipcb) {
00593
00594 LWIP_ASSERT("rebind == 0", rebind == 0);
00595
00596 rebind = 1;
00597 }
00598
00599
00600
00601
00602
00603 #ifdef LWIP_UDP_TODO
00604
00605 else
00606 if ((ipcb->local_port == port) &&
00607
00608 (ip_addr_isany(&(ipcb->local_ip)) ||
00609 ip_addr_isany(ipaddr) ||
00610 ip_addr_cmp(&(ipcb->local_ip), ipaddr))) {
00611
00612 LWIP_DEBUGF(UDP_DEBUG,
00613 ("udp_bind: local port %"U16_F" already bound by another pcb\n", port));
00614 return ERR_USE;
00615 }
00616 #endif
00617 }
00618
00619 ip_addr_set(&pcb->local_ip, ipaddr);
00620
00621
00622 if (port == 0) {
00623 #ifndef UDP_LOCAL_PORT_RANGE_START
00624 #define UDP_LOCAL_PORT_RANGE_START 4096
00625 #define UDP_LOCAL_PORT_RANGE_END 0x7fff
00626 #endif
00627 port = UDP_LOCAL_PORT_RANGE_START;
00628 ipcb = udp_pcbs;
00629 while ((ipcb != NULL) && (port != UDP_LOCAL_PORT_RANGE_END)) {
00630 if (ipcb->local_port == port) {
00631
00632 port++;
00633
00634 ipcb = udp_pcbs;
00635 } else
00636
00637 ipcb = ipcb->next;
00638 }
00639 if (ipcb != NULL) {
00640
00641 LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n"));
00642 return ERR_USE;
00643 }
00644 }
00645 pcb->local_port = port;
00646 snmp_insert_udpidx_tree(pcb);
00647
00648 if (rebind == 0) {
00649
00650 pcb->next = udp_pcbs;
00651 udp_pcbs = pcb;
00652 }
00653 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00654 ("udp_bind: bound to %"U16_F".%"U16_F".%"U16_F".%"U16_F", port %"U16_F"\n",
00655 (u16_t)((ntohl(pcb->local_ip.addr) >> 24) & 0xff),
00656 (u16_t)((ntohl(pcb->local_ip.addr) >> 16) & 0xff),
00657 (u16_t)((ntohl(pcb->local_ip.addr) >> 8) & 0xff),
00658 (u16_t)(ntohl(pcb->local_ip.addr) & 0xff), pcb->local_port));
00659 return ERR_OK;
00660 }
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 err_t
00679 udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
00680 {
00681 struct udp_pcb *ipcb;
00682
00683 if (pcb->local_port == 0) {
00684 err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
00685 if (err != ERR_OK)
00686 return err;
00687 }
00688
00689 ip_addr_set(&pcb->remote_ip, ipaddr);
00690 pcb->remote_port = port;
00691 pcb->flags |= UDP_FLAGS_CONNECTED;
00692
00693 #ifdef LWIP_UDP_TODO
00694
00695 if (ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) {
00696 struct netif *netif;
00697
00698 if ((netif = ip_route(&(pcb->remote_ip))) == NULL) {
00699 LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr));
00700 UDP_STATS_INC(udp.rterr);
00701 return ERR_RTE;
00702 }
00703
00704
00705
00706 pcb->local_ip = netif->ip_addr;
00707 } else if (ip_addr_isany(&pcb->remote_ip)) {
00708 pcb->local_ip.addr = 0;
00709 }
00710 #endif
00711 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
00712 ("udp_connect: connected to %"U16_F".%"U16_F".%"U16_F".%"U16_F",port %"U16_F"\n",
00713 (u16_t)((ntohl(pcb->remote_ip.addr) >> 24) & 0xff),
00714 (u16_t)((ntohl(pcb->remote_ip.addr) >> 16) & 0xff),
00715 (u16_t)((ntohl(pcb->remote_ip.addr) >> 8) & 0xff),
00716 (u16_t)(ntohl(pcb->remote_ip.addr) & 0xff), pcb->remote_port));
00717
00718
00719 for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
00720 if (pcb == ipcb) {
00721
00722 return ERR_OK;
00723 }
00724 }
00725
00726 pcb->next = udp_pcbs;
00727 udp_pcbs = pcb;
00728 return ERR_OK;
00729 }
00730
00731
00732
00733
00734
00735
00736 void
00737 udp_disconnect(struct udp_pcb *pcb)
00738 {
00739
00740 ip_addr_set(&pcb->remote_ip, IP_ADDR_ANY);
00741 pcb->remote_port = 0;
00742
00743 pcb->flags &= ~UDP_FLAGS_CONNECTED;
00744 }
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755 void
00756 udp_recv(struct udp_pcb *pcb,
00757 void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p,
00758 struct ip_addr *addr, u16_t port),
00759 void *recv_arg)
00760 {
00761
00762 pcb->recv = recv;
00763 pcb->recv_arg = recv_arg;
00764 }
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 void
00775 udp_remove(struct udp_pcb *pcb)
00776 {
00777 struct udp_pcb *pcb2;
00778
00779 snmp_delete_udpidx_tree(pcb);
00780
00781 if (udp_pcbs == pcb) {
00782
00783 udp_pcbs = udp_pcbs->next;
00784
00785 } else
00786 for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
00787
00788 if (pcb2->next != NULL && pcb2->next == pcb) {
00789
00790 pcb2->next = pcb->next;
00791 }
00792 }
00793 memp_free(MEMP_UDP_PCB, pcb);
00794 }
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804 struct udp_pcb *
00805 udp_new(void)
00806 {
00807 struct udp_pcb *pcb;
00808 pcb = memp_malloc(MEMP_UDP_PCB);
00809
00810 if (pcb != NULL) {
00811
00812
00813
00814
00815 memset(pcb, 0, sizeof(struct udp_pcb));
00816 pcb->ttl = UDP_TTL;
00817 }
00818 return pcb;
00819 }
00820
00821 #if UDP_DEBUG
00822
00823
00824
00825
00826
00827 void
00828 udp_debug_print(struct udp_hdr *udphdr)
00829 {
00830 LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n"));
00831 LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
00832 LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n",
00833 ntohs(udphdr->src), ntohs(udphdr->dest)));
00834 LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
00835 LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | 0x%04"X16_F" | (len, chksum)\n",
00836 ntohs(udphdr->len), ntohs(udphdr->chksum)));
00837 LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
00838 }
00839 #endif
00840
00841 #endif