Warning, cross-references for /kernel/lwip/core/udp.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 #include "lwip/opt.h"
0050
0051 #if LWIP_UDP
0052
0053 #include "lwip/udp.h"
0054 #include "lwip/def.h"
0055 #include "lwip/memp.h"
0056 #include "lwip/inet.h"
0057 #include "lwip/inet_chksum.h"
0058 #include "lwip/ip_addr.h"
0059 #include "lwip/netif.h"
0060 #include "lwip/icmp.h"
0061 #include "lwip/stats.h"
0062 #include "lwip/snmp.h"
0063 #include "arch/perf.h"
0064 #include "lwip/dhcp.h"
0065
0066 #include <string.h>
0067
0068
0069
0070 struct udp_pcb *udp_pcbs;
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084 void
0085 udp_input(struct pbuf *p, struct netif *inp)
0086 {
0087 struct udp_hdr *udphdr;
0088 struct udp_pcb *pcb, *prev;
0089 struct udp_pcb *uncon_pcb;
0090 struct ip_hdr *iphdr;
0091 u16_t src, dest;
0092 u8_t local_match;
0093 u8_t broadcast;
0094
0095 PERF_START;
0096
0097 UDP_STATS_INC(udp.recv);
0098
0099 iphdr = p->payload;
0100
0101
0102
0103 if (p->tot_len < (IPH_HL(iphdr) * 4 + UDP_HLEN) || pbuf_header(p, -(s16_t)(IPH_HL(iphdr) * 4))) {
0104
0105 LWIP_DEBUGF(UDP_DEBUG,
0106 ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len));
0107 UDP_STATS_INC(udp.lenerr);
0108 UDP_STATS_INC(udp.drop);
0109 snmp_inc_udpinerrors();
0110 pbuf_free(p);
0111 goto end;
0112 }
0113
0114 udphdr = (struct udp_hdr *)p->payload;
0115
0116
0117 broadcast = ip_addr_isbroadcast(&(iphdr->dest), inp);
0118
0119 LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len));
0120
0121
0122 src = ntohs(udphdr->src);
0123 dest = ntohs(udphdr->dest);
0124
0125 udp_debug_print(udphdr);
0126
0127
0128 LWIP_DEBUGF(UDP_DEBUG,
0129 ("udp (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") <-- "
0130 "(%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n",
0131 ip4_addr1(&iphdr->dest), ip4_addr2(&iphdr->dest),
0132 ip4_addr3(&iphdr->dest), ip4_addr4(&iphdr->dest), ntohs(udphdr->dest),
0133 ip4_addr1(&iphdr->src), ip4_addr2(&iphdr->src),
0134 ip4_addr3(&iphdr->src), ip4_addr4(&iphdr->src), ntohs(udphdr->src)));
0135
0136 #if LWIP_DHCP
0137 pcb = NULL;
0138
0139
0140 if (dest == DHCP_CLIENT_PORT) {
0141
0142 if (src == DHCP_SERVER_PORT) {
0143 if ((inp->dhcp != NULL) && (inp->dhcp->pcb != NULL)) {
0144
0145
0146
0147 if ((ip_addr_isany(&inp->dhcp->pcb->remote_ip) ||
0148 ip_addr_cmp(&(inp->dhcp->pcb->remote_ip), &(iphdr->src)))) {
0149 pcb = inp->dhcp->pcb;
0150 }
0151 }
0152 }
0153 } else
0154 #endif
0155 {
0156 prev = NULL;
0157 local_match = 0;
0158 uncon_pcb = NULL;
0159
0160
0161
0162
0163 for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
0164 local_match = 0;
0165
0166 LWIP_DEBUGF(UDP_DEBUG,
0167 ("pcb (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") --- "
0168 "(%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n",
0169 ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip),
0170 ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port,
0171 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
0172 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));
0173
0174
0175 if ((pcb->local_port == dest) &&
0176 ((!broadcast && ip_addr_isany(&pcb->local_ip)) ||
0177 ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)) ||
0178 #if LWIP_IGMP
0179 ip_addr_ismulticast(&(iphdr->dest)) ||
0180 #endif
0181 #if IP_SOF_BROADCAST_RECV
0182 (broadcast && (pcb->so_options & SOF_BROADCAST)))) {
0183 #else
0184 (broadcast))) {
0185 #endif
0186 local_match = 1;
0187 if ((uncon_pcb == NULL) &&
0188 ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) {
0189
0190 uncon_pcb = pcb;
0191 }
0192 }
0193
0194 if ((local_match != 0) &&
0195 (pcb->remote_port == src) &&
0196 (ip_addr_isany(&pcb->remote_ip) ||
0197 ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)))) {
0198
0199 if (prev != NULL) {
0200
0201
0202 prev->next = pcb->next;
0203 pcb->next = udp_pcbs;
0204 udp_pcbs = pcb;
0205 } else {
0206 UDP_STATS_INC(udp.cachehit);
0207 }
0208 break;
0209 }
0210 prev = pcb;
0211 }
0212
0213 if (pcb == NULL) {
0214 pcb = uncon_pcb;
0215 }
0216 }
0217
0218
0219 if (pcb != NULL || ip_addr_cmp(&inp->ip_addr, &iphdr->dest)) {
0220 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n"));
0221 #if LWIP_UDPLITE
0222 if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
0223
0224 #if CHECKSUM_CHECK_UDP
0225 u16_t chklen = ntohs(udphdr->len);
0226 if (chklen < sizeof(struct udp_hdr)) {
0227 if (chklen == 0) {
0228
0229
0230 chklen = p->tot_len;
0231 } else {
0232
0233
0234 UDP_STATS_INC(udp.chkerr);
0235 UDP_STATS_INC(udp.drop);
0236 snmp_inc_udpinerrors();
0237 pbuf_free(p);
0238 goto end;
0239 }
0240 }
0241 if (inet_chksum_pseudo_partial(p, (struct ip_addr *)&(iphdr->src),
0242 (struct ip_addr *)&(iphdr->dest),
0243 IP_PROTO_UDPLITE, p->tot_len, chklen) != 0) {
0244 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
0245 ("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
0246 UDP_STATS_INC(udp.chkerr);
0247 UDP_STATS_INC(udp.drop);
0248 snmp_inc_udpinerrors();
0249 pbuf_free(p);
0250 goto end;
0251 }
0252 #endif
0253 } else
0254 #endif
0255 {
0256 #if CHECKSUM_CHECK_UDP
0257 if (udphdr->chksum != 0) {
0258 if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
0259 (struct ip_addr *)&(iphdr->dest),
0260 IP_PROTO_UDP, p->tot_len) != 0) {
0261 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
0262 ("udp_input: UDP datagram discarded due to failing checksum\n"));
0263 UDP_STATS_INC(udp.chkerr);
0264 UDP_STATS_INC(udp.drop);
0265 snmp_inc_udpinerrors();
0266 pbuf_free(p);
0267 goto end;
0268 }
0269 }
0270 #endif
0271 }
0272 if(pbuf_header(p, -UDP_HLEN)) {
0273
0274 LWIP_ASSERT("pbuf_header failed\n", 0);
0275 UDP_STATS_INC(udp.drop);
0276 snmp_inc_udpinerrors();
0277 pbuf_free(p);
0278 goto end;
0279 }
0280 if (pcb != NULL) {
0281 snmp_inc_udpindatagrams();
0282
0283 if (pcb->recv != NULL) {
0284
0285 pcb->recv(pcb->recv_arg, pcb, p, &iphdr->src, src);
0286 } else {
0287
0288 pbuf_free(p);
0289 goto end;
0290 }
0291 } else {
0292 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: not for us.\n"));
0293
0294 #if LWIP_ICMP
0295
0296
0297 if (!broadcast &&
0298 !ip_addr_ismulticast(&iphdr->dest)) {
0299
0300 pbuf_header(p, (IPH_HL(iphdr) * 4) + UDP_HLEN);
0301 LWIP_ASSERT("p->payload == iphdr", (p->payload == iphdr));
0302 icmp_dest_unreach(p, ICMP_DUR_PORT);
0303 }
0304 #endif
0305 UDP_STATS_INC(udp.proterr);
0306 UDP_STATS_INC(udp.drop);
0307 snmp_inc_udpnoports();
0308 pbuf_free(p);
0309 }
0310 } else {
0311 pbuf_free(p);
0312 }
0313 end:
0314 PERF_STOP("udp_input");
0315 }
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335 err_t
0336 udp_send(struct udp_pcb *pcb, struct pbuf *p)
0337 {
0338
0339 return udp_sendto(pcb, p, &pcb->remote_ip, pcb->remote_port);
0340 }
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359 err_t
0360 udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
0361 struct ip_addr *dst_ip, u16_t dst_port)
0362 {
0363 struct netif *netif;
0364
0365 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n"));
0366
0367
0368 #if LWIP_IGMP
0369 netif = ip_route((ip_addr_ismulticast(dst_ip))?(&(pcb->multicast_ip)):(dst_ip));
0370 #else
0371 netif = ip_route(dst_ip);
0372 #endif
0373
0374
0375 if (netif == NULL) {
0376 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to 0x%"X32_F"\n", dst_ip->addr));
0377 UDP_STATS_INC(udp.rterr);
0378 return ERR_RTE;
0379 }
0380 return udp_sendto_if(pcb, p, dst_ip, dst_port, netif);
0381 }
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402 err_t
0403 udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p,
0404 struct ip_addr *dst_ip, u16_t dst_port, struct netif *netif)
0405 {
0406 struct udp_hdr *udphdr;
0407 struct ip_addr *src_ip;
0408 err_t err;
0409 struct pbuf *q;
0410
0411 #if IP_SOF_BROADCAST
0412
0413 if ( ((pcb->so_options & SOF_BROADCAST) == 0) && ip_addr_isbroadcast(dst_ip, netif) ) {
0414 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
0415 ("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
0416 return ERR_VAL;
0417 }
0418 #endif
0419
0420
0421 if (pcb->local_port == 0) {
0422 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n"));
0423 err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
0424 if (err != ERR_OK) {
0425 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n"));
0426 return err;
0427 }
0428 }
0429
0430
0431 if (pbuf_header(p, UDP_HLEN)) {
0432
0433 q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);
0434
0435 if (q == NULL) {
0436 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n"));
0437 return ERR_MEM;
0438 }
0439
0440 pbuf_chain(q, p);
0441
0442 LWIP_DEBUGF(UDP_DEBUG,
0443 ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
0444 } else {
0445
0446
0447 q = p;
0448 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));
0449 }
0450 LWIP_ASSERT("check that first pbuf can hold struct udp_hdr",
0451 (q->len >= sizeof(struct udp_hdr)));
0452
0453 udphdr = q->payload;
0454 udphdr->src = htons(pcb->local_port);
0455 udphdr->dest = htons(dst_port);
0456
0457 udphdr->chksum = 0x0000;
0458
0459
0460 if (ip_addr_isany(&pcb->local_ip)) {
0461
0462 src_ip = &(netif->ip_addr);
0463 } else {
0464
0465
0466 if (!ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {
0467
0468 if (q != p) {
0469
0470 pbuf_free(q);
0471 q = NULL;
0472
0473 }
0474 return ERR_VAL;
0475 }
0476
0477 src_ip = &(pcb->local_ip);
0478 }
0479
0480 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len));
0481
0482 #if LWIP_UDPLITE
0483
0484 if (pcb->flags & UDP_FLAGS_UDPLITE) {
0485 u16_t chklen, chklen_hdr;
0486 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len));
0487
0488 chklen_hdr = chklen = pcb->chksum_len_tx;
0489 if ((chklen < sizeof(struct udp_hdr)) || (chklen > q->tot_len)) {
0490 if (chklen != 0) {
0491 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE pcb->chksum_len is illegal: %"U16_F"\n", chklen));
0492 }
0493
0494
0495
0496
0497
0498
0499 chklen_hdr = 0;
0500 chklen = q->tot_len;
0501 }
0502 udphdr->len = htons(chklen_hdr);
0503
0504 #if CHECKSUM_GEN_UDP
0505 udphdr->chksum = inet_chksum_pseudo_partial(q, src_ip, dst_ip,
0506 IP_PROTO_UDPLITE, q->tot_len, chklen);
0507
0508 if (udphdr->chksum == 0x0000)
0509 udphdr->chksum = 0xffff;
0510 #endif
0511
0512 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));
0513 #if LWIP_NETIF_HWADDRHINT
0514 netif->addr_hint = &(pcb->addr_hint);
0515 #endif
0516 err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);
0517 #if LWIP_NETIF_HWADDRHINT
0518 netif->addr_hint = NULL;
0519 #endif
0520 } else
0521 #endif
0522 {
0523 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len));
0524 udphdr->len = htons(q->tot_len);
0525
0526 #if CHECKSUM_GEN_UDP
0527 if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
0528 udphdr->chksum = inet_chksum_pseudo(q, src_ip, dst_ip, IP_PROTO_UDP, q->tot_len);
0529
0530 if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
0531 }
0532 #endif
0533 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum));
0534 LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
0535
0536 #if LWIP_NETIF_HWADDRHINT
0537 netif->addr_hint = &(pcb->addr_hint);
0538 #endif
0539 err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);
0540 #if LWIP_NETIF_HWADDRHINT
0541 netif->addr_hint = NULL;
0542 #endif
0543 }
0544
0545 snmp_inc_udpoutdatagrams();
0546
0547
0548 if (q != p) {
0549
0550 pbuf_free(q);
0551 q = NULL;
0552
0553 }
0554
0555 UDP_STATS_INC(udp.xmit);
0556 return err;
0557 }
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578 err_t
0579 udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
0580 {
0581 struct udp_pcb *ipcb;
0582 u8_t rebind;
0583
0584 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = "));
0585 ip_addr_debug_print(UDP_DEBUG, ipaddr);
0586 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port));
0587
0588 rebind = 0;
0589
0590 for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
0591
0592 if (pcb == ipcb) {
0593
0594 LWIP_ASSERT("rebind == 0", rebind == 0);
0595
0596 rebind = 1;
0597 }
0598
0599
0600
0601
0602
0603 #ifdef LWIP_UDP_TODO
0604
0605 else
0606 if ((ipcb->local_port == port) &&
0607
0608 (ip_addr_isany(&(ipcb->local_ip)) ||
0609 ip_addr_isany(ipaddr) ||
0610 ip_addr_cmp(&(ipcb->local_ip), ipaddr))) {
0611
0612 LWIP_DEBUGF(UDP_DEBUG,
0613 ("udp_bind: local port %"U16_F" already bound by another pcb\n", port));
0614 return ERR_USE;
0615 }
0616 #endif
0617 }
0618
0619 ip_addr_set(&pcb->local_ip, ipaddr);
0620
0621
0622 if (port == 0) {
0623 #ifndef UDP_LOCAL_PORT_RANGE_START
0624 #define UDP_LOCAL_PORT_RANGE_START 4096
0625 #define UDP_LOCAL_PORT_RANGE_END 0x7fff
0626 #endif
0627 port = UDP_LOCAL_PORT_RANGE_START;
0628 ipcb = udp_pcbs;
0629 while ((ipcb != NULL) && (port != UDP_LOCAL_PORT_RANGE_END)) {
0630 if (ipcb->local_port == port) {
0631
0632 port++;
0633
0634 ipcb = udp_pcbs;
0635 } else
0636
0637 ipcb = ipcb->next;
0638 }
0639 if (ipcb != NULL) {
0640
0641 LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n"));
0642 return ERR_USE;
0643 }
0644 }
0645 pcb->local_port = port;
0646 snmp_insert_udpidx_tree(pcb);
0647
0648 if (rebind == 0) {
0649
0650 pcb->next = udp_pcbs;
0651 udp_pcbs = pcb;
0652 }
0653 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
0654 ("udp_bind: bound to %"U16_F".%"U16_F".%"U16_F".%"U16_F", port %"U16_F"\n",
0655 (u16_t)((ntohl(pcb->local_ip.addr) >> 24) & 0xff),
0656 (u16_t)((ntohl(pcb->local_ip.addr) >> 16) & 0xff),
0657 (u16_t)((ntohl(pcb->local_ip.addr) >> 8) & 0xff),
0658 (u16_t)(ntohl(pcb->local_ip.addr) & 0xff), pcb->local_port));
0659 return ERR_OK;
0660 }
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678 err_t
0679 udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
0680 {
0681 struct udp_pcb *ipcb;
0682
0683 if (pcb->local_port == 0) {
0684 err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
0685 if (err != ERR_OK)
0686 return err;
0687 }
0688
0689 ip_addr_set(&pcb->remote_ip, ipaddr);
0690 pcb->remote_port = port;
0691 pcb->flags |= UDP_FLAGS_CONNECTED;
0692
0693 #ifdef LWIP_UDP_TODO
0694
0695 if (ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) {
0696 struct netif *netif;
0697
0698 if ((netif = ip_route(&(pcb->remote_ip))) == NULL) {
0699 LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr));
0700 UDP_STATS_INC(udp.rterr);
0701 return ERR_RTE;
0702 }
0703
0704
0705
0706 pcb->local_ip = netif->ip_addr;
0707 } else if (ip_addr_isany(&pcb->remote_ip)) {
0708 pcb->local_ip.addr = 0;
0709 }
0710 #endif
0711 LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
0712 ("udp_connect: connected to %"U16_F".%"U16_F".%"U16_F".%"U16_F",port %"U16_F"\n",
0713 (u16_t)((ntohl(pcb->remote_ip.addr) >> 24) & 0xff),
0714 (u16_t)((ntohl(pcb->remote_ip.addr) >> 16) & 0xff),
0715 (u16_t)((ntohl(pcb->remote_ip.addr) >> 8) & 0xff),
0716 (u16_t)(ntohl(pcb->remote_ip.addr) & 0xff), pcb->remote_port));
0717
0718
0719 for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
0720 if (pcb == ipcb) {
0721
0722 return ERR_OK;
0723 }
0724 }
0725
0726 pcb->next = udp_pcbs;
0727 udp_pcbs = pcb;
0728 return ERR_OK;
0729 }
0730
0731
0732
0733
0734
0735
0736 void
0737 udp_disconnect(struct udp_pcb *pcb)
0738 {
0739
0740 ip_addr_set(&pcb->remote_ip, IP_ADDR_ANY);
0741 pcb->remote_port = 0;
0742
0743 pcb->flags &= ~UDP_FLAGS_CONNECTED;
0744 }
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755 void
0756 udp_recv(struct udp_pcb *pcb,
0757 void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p,
0758 struct ip_addr *addr, u16_t port),
0759 void *recv_arg)
0760 {
0761
0762 pcb->recv = recv;
0763 pcb->recv_arg = recv_arg;
0764 }
0765
0766
0767
0768
0769
0770
0771
0772
0773
0774 void
0775 udp_remove(struct udp_pcb *pcb)
0776 {
0777 struct udp_pcb *pcb2;
0778
0779 snmp_delete_udpidx_tree(pcb);
0780
0781 if (udp_pcbs == pcb) {
0782
0783 udp_pcbs = udp_pcbs->next;
0784
0785 } else
0786 for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
0787
0788 if (pcb2->next != NULL && pcb2->next == pcb) {
0789
0790 pcb2->next = pcb->next;
0791 }
0792 }
0793 memp_free(MEMP_UDP_PCB, pcb);
0794 }
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804 struct udp_pcb *
0805 udp_new(void)
0806 {
0807 struct udp_pcb *pcb;
0808 pcb = memp_malloc(MEMP_UDP_PCB);
0809
0810 if (pcb != NULL) {
0811
0812
0813
0814
0815 memset(pcb, 0, sizeof(struct udp_pcb));
0816 pcb->ttl = UDP_TTL;
0817 }
0818 return pcb;
0819 }
0820
0821 #if UDP_DEBUG
0822
0823
0824
0825
0826
0827 void
0828 udp_debug_print(struct udp_hdr *udphdr)
0829 {
0830 LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n"));
0831 LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
0832 LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n",
0833 ntohs(udphdr->src), ntohs(udphdr->dest)));
0834 LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
0835 LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | 0x%04"X16_F" | (len, chksum)\n",
0836 ntohs(udphdr->len), ntohs(udphdr->chksum)));
0837 LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
0838 }
0839 #endif
0840
0841 #endif