00001
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
00050
00051 #include "lwip/opt.h"
00052
00053 #include "lwip/def.h"
00054 #include "lwip/memp.h"
00055 #include "lwip/inet.h"
00056 #include "lwip/netif.h"
00057 #include "lwip/udp.h"
00058 #include "lwip/icmp.h"
00059 #include "lwip/ip_addr.h"
00060
00061 #include "lwip/stats.h"
00062
00063
00064 #include "lwip/snmp.h"
00065
00066 #define htons HTONS
00067 #define htonl HTONL
00068
00069
00070
00071
00072
00073 #if LWIP_UDP
00074
00075 struct udp_pcb *udp_pcbs = NULL;
00076
00077 static struct udp_pcb *pcb_cache = NULL;
00078
00079 #if UDP_DEBUG
00080 int udp_debug_print(struct udp_hdr *udphdr);
00081 #endif
00082
00083
00084 void
00085 udp_init(void)
00086 {
00087 udp_pcbs = pcb_cache = NULL;
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097 #ifdef LWIP_DEBUG
00098 u8_t
00099 udp_lookup(struct ip_hdr *iphdr, struct netif *inp)
00100 {
00101 struct udp_pcb *pcb;
00102 struct udp_hdr *udphdr;
00103 u16_t src, dest;
00104
00105
00106 (void)inp;
00107
00108 udphdr = (struct udp_hdr *)(u8_t *)iphdr + IPH_HL(iphdr) * 4;
00109
00110 src = ntohs(udphdr->src);
00111 dest = ntohs(udphdr->dest);
00112
00113 pcb = pcb_cache;
00114 if(pcb != NULL &&
00115 pcb->remote_port == src &&
00116 pcb->local_port == dest &&
00117 (ip_addr_isany(&pcb->remote_ip) ||
00118 ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
00119 (ip_addr_isany(&pcb->local_ip) ||
00120 ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
00121 return 1;
00122 }
00123 else {
00124 for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
00125 if(pcb->remote_port == src &&
00126 pcb->local_port == dest &&
00127 (ip_addr_isany(&pcb->remote_ip) ||
00128 ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
00129 (ip_addr_isany(&pcb->local_ip) ||
00130 ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
00131 pcb_cache = pcb;
00132 break;
00133 }
00134 }
00135
00136 if(pcb == NULL) {
00137 for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
00138 if(pcb->remote_port == 0 &&
00139 pcb->local_port == dest &&
00140 (ip_addr_isany(&pcb->remote_ip) ||
00141 ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
00142 (ip_addr_isany(&pcb->local_ip) ||
00143 ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
00144 break;
00145 }
00146 }
00147 }
00148 }
00149
00150
00151
00152 if(pcb != NULL) {
00153 return 1;
00154 }
00155 else {
00156 return 1;
00157 }
00158 }
00159 #endif
00160
00171 void
00172 udp_input(struct pbuf *p, struct netif *inp)
00173 {
00174 struct udp_hdr *udphdr;
00175 struct udp_pcb *pcb;
00176 struct ip_hdr *iphdr;
00177 u16_t src, dest;
00178
00179
00180
00181 #ifdef UDP_STATS
00182 ++lwip_stats.udp.recv;
00183 #endif
00184
00185 iphdr = p->payload;
00186
00187 pbuf_header(p, -((s16_t)(UDP_HLEN + IPH_HL(iphdr) * 4)));
00188
00189 udphdr = (struct udp_hdr *)((u8_t *)p->payload - UDP_HLEN);
00190
00191 DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %u\n", p->tot_len));
00192
00193 src = ntohs(udphdr->src);
00194 dest = ntohs(udphdr->dest);
00195
00196 #if UDP_DEBUG
00197 udp_debug_print(udphdr);
00198 #endif
00199
00200
00201 DEBUGF(UDP_DEBUG, ("udp (%u.%u.%u.%u, %u) <-- (%u.%u.%u.%u, %u)\n",
00202 ip4_addr1(&iphdr->dest), ip4_addr2(&iphdr->dest),
00203 ip4_addr3(&iphdr->dest), ip4_addr4(&iphdr->dest), ntohs(udphdr->dest),
00204 ip4_addr1(&iphdr->src), ip4_addr2(&iphdr->src),
00205 ip4_addr3(&iphdr->src), ip4_addr4(&iphdr->src), ntohs(udphdr->src)));
00206
00207 for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
00208
00209 DEBUGF(UDP_DEBUG, ("pcb (%u.%u.%u.%u, %u) --- (%u.%u.%u.%u, %u)\n",
00210 ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip),
00211 ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port,
00212 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
00213 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));
00214
00215
00216 if((pcb->remote_port == src) &&
00217
00218 (pcb->local_port == dest) &&
00219
00220 (ip_addr_isany(&pcb->remote_ip) ||
00221
00222 ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
00223
00224 (ip_addr_isany(&pcb->local_ip) ||
00225
00226 ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
00227 break;
00228 }
00229 }
00230
00231 if (pcb == NULL) {
00232
00233
00234 for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
00235 DEBUGF(UDP_DEBUG, ("pcb (%u.%u.%u.%u, %u) --- (%u.%u.%u.%u, %u)\n",
00236 ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip),
00237 ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port,
00238 ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip),
00239 ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port));
00240
00241 if(((pcb->flags & UDP_FLAGS_CONNECTED) == 0) &&
00242
00243 (pcb->local_port == dest) &&
00244
00245 (ip_addr_isany(&pcb->local_ip) ||
00246
00247 ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
00248 break;
00249 }
00250 }
00251 }
00252
00253
00254 if(pcb != NULL || ip_addr_cmp(&inp->ip_addr, &iphdr->dest))
00255 {
00256 DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: calculating checksum\n"));
00257 pbuf_header(p, UDP_HLEN);
00258 #ifdef IPv6
00259 if(iphdr->nexthdr == IP_PROTO_UDPLITE) {
00260 #else
00261 if(IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) {
00262 #endif
00263
00264 if(inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
00265 (struct ip_addr *)&(iphdr->dest),
00266 IP_PROTO_UDPLITE, ntohs(udphdr->len)) != 0) {
00267 DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP Lite datagram discarded due to failing checksum\n"));
00268 #ifdef UDP_STATS
00269 ++lwip_stats.udp.chkerr;
00270 ++lwip_stats.udp.drop;
00271 #endif
00272 snmp_inc_udpinerrors();
00273 pbuf_free(p);
00274 goto end;
00275 }
00276 } else {
00277 if(udphdr->chksum != 0) {
00278 if(inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src),
00279 (struct ip_addr *)&(iphdr->dest),
00280 IP_PROTO_UDP, p->tot_len) != 0) {
00281 DEBUGF(UDP_DEBUG | 2, ("udp_input: UDP datagram discarded due to failing checksum\n"));
00282
00283 #ifdef UDP_STATS
00284 ++lwip_stats.udp.chkerr;
00285 ++lwip_stats.udp.drop;
00286 #endif
00287 snmp_inc_udpinerrors();
00288 pbuf_free(p);
00289 goto end;
00290 }
00291 }
00292 }
00293 pbuf_header(p, -UDP_HLEN);
00294 if(pcb != NULL) {
00295 snmp_inc_udpindatagrams();
00296 pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);
00297 } else {
00298 DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: not for us.\n"));
00299
00300
00301
00302
00303 if(!ip_addr_isbroadcast(&iphdr->dest, &inp->netmask) &&
00304 !ip_addr_ismulticast(&iphdr->dest)) {
00305
00306
00307 p->payload = iphdr;
00308 icmp_dest_unreach(p, ICMP_DUR_PORT);
00309 }
00310 #ifdef UDP_STATS
00311 ++lwip_stats.udp.proterr;
00312 ++lwip_stats.udp.drop;
00313 #endif
00314 snmp_inc_udpnoports();
00315 pbuf_free(p);
00316 }
00317 } else {
00318 pbuf_free(p);
00319 }
00320 end:
00321
00322
00323 }
00338 err_t
00339 udp_send(struct udp_pcb *pcb, struct pbuf *p)
00340 {
00341 struct udp_hdr *udphdr;
00342 struct netif *netif;
00343 struct ip_addr *src_ip;
00344 err_t err;
00345 struct pbuf *q;
00346
00347 DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_send\n"));
00348
00349
00350 if (pcb->local_port == 0) {
00351 DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: not yet bound\n"));
00352 err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
00353 if (err != ERR_OK) {
00354 DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: forced bind failed\n"));
00355 return err;
00356 }
00357 }
00358
00359
00360 if (pbuf_header(p, UDP_HLEN)) {
00361
00362 q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);
00363
00364 if (q == NULL) {
00365 DEBUGF(UDP_DEBUG | DBG_TRACE | 2, ("udp_send: could not allocate header\n"));
00366 return ERR_MEM;
00367 }
00368
00369 pbuf_chain(q, p);
00370
00371 DEBUGF(UDP_DEBUG, ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
00372 } else {
00373
00374 q = p;
00375 DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));
00376 }
00377
00378 udphdr = q->payload;
00379 udphdr->src = htons(pcb->local_port);
00380 udphdr->dest = htons(pcb->remote_port);
00381 udphdr->chksum = 0x0000;
00382
00383 if((netif = ip_route(&(pcb->remote_ip))) == NULL) {
00384 DEBUGF(UDP_DEBUG | 1, ("udp_send: No route to 0x%lx\n", pcb->remote_ip.addr));
00385 #ifdef UDP_STATS
00386 ++lwip_stats.udp.rterr;
00387 #endif
00388 return ERR_RTE;
00389 }
00390
00391 if(ip_addr_isany(&pcb->local_ip)) {
00392
00393 src_ip = &(netif->ip_addr);
00394 } else {
00395
00396 src_ip = &(pcb->local_ip);
00397 }
00398
00399 DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %u\n", q->tot_len));
00400
00401
00402 if(pcb->flags & UDP_FLAGS_UDPLITE) {
00403 DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %u\n", q->tot_len));
00404
00405 udphdr->len = htons(pcb->chksum_len);
00406
00407 udphdr->chksum = inet_chksum_pseudo(q, src_ip, &(pcb->remote_ip),
00408 IP_PROTO_UDP, pcb->chksum_len);
00409
00410 if(udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
00411
00412 err = ip_output_if(q, src_ip, &pcb->remote_ip, UDP_TTL, IP_PROTO_UDPLITE, netif);
00413 snmp_inc_udpoutdatagrams();
00414 } else {
00415 DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %u\n", q->tot_len));
00416 udphdr->len = htons(q->tot_len);
00417
00418 if((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
00419 udphdr->chksum = inet_chksum_pseudo(q, src_ip, &pcb->remote_ip, IP_PROTO_UDP, q->tot_len);
00420
00421 if(udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
00422 }
00423 DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04x\n", udphdr->chksum));
00424 snmp_inc_udpoutdatagrams();
00425 DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if(,,,,IP_PROTO_UDP,)\n"));
00426
00427 err = ip_output_if(q, src_ip, &pcb->remote_ip, UDP_TTL, IP_PROTO_UDP, netif);
00428 }
00429
00430
00431 if (q != p) {
00432
00433 pbuf_free(q);
00434 }
00435
00436 #ifdef UDP_STATS
00437 ++lwip_stats.udp.xmit;
00438 #endif
00439 return err;
00440 }
00441
00457 err_t
00458 udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
00459 {
00460 struct udp_pcb *ipcb;
00461 u8_t rebind;
00462 DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_bind(ipaddr = %lx, port = %u)\n", ipaddr->addr, port));
00463 rebind = 0;
00464
00465 for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
00466
00467 if (pcb == ipcb) {
00468
00469 LWIP_ASSERT("rebind == 0", rebind == 0);
00470
00471 rebind = 1;
00472 }
00473
00474
00475
00476
00477 #if 0
00478
00479 else if ((ipcb->local_port == port) &&
00480
00481 (ip_addr_isany(&(ipcb->local_ip)) ||
00482 ip_addr_isany(ipaddr) ||
00483 ip_addr_cmp(&(ipcb->local_ip), ipaddr))) {
00484
00485 DEBUGF(UDP_DEBUG, ("udp_bind: local port %u already bound by another pcb\n", port));
00486 return ERR_USE;
00487 }
00488 #endif
00489 }
00490
00491 ip_addr_set(&pcb->local_ip, ipaddr);
00492
00493 if (port == 0) {
00494 #ifndef UDP_LOCAL_PORT_RANGE_START
00495 #define UDP_LOCAL_PORT_RANGE_START 4096
00496 #define UDP_LOCAL_PORT_RANGE_END 0x7fff
00497 #endif
00498 port = UDP_LOCAL_PORT_RANGE_START;
00499 ipcb = udp_pcbs;
00500 while ((ipcb != NULL) && (port != UDP_LOCAL_PORT_RANGE_END)) {
00501 if (ipcb->local_port == port) {
00502 port++;
00503 ipcb = udp_pcbs;
00504 } else
00505 ipcb = ipcb->next;
00506 }
00507 if (ipcb != NULL) {
00508
00509 DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n"));
00510 return ERR_USE;
00511 }
00512 }
00513 pcb->local_port = port;
00514
00515 if (rebind == 0) {
00516
00517 pcb->next = udp_pcbs;
00518 udp_pcbs = pcb;
00519 }
00520 DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_bind: bound to %u.%u.%u.%u, port %u\n",
00521 (u8_t)(ntohl(pcb->local_ip.addr) >> 24 & 0xff),
00522 (u8_t)(ntohl(pcb->local_ip.addr) >> 16 & 0xff),
00523 (u8_t)(ntohl(pcb->local_ip.addr) >> 8 & 0xff),
00524 (u8_t)(ntohl(pcb->local_ip.addr) & 0xff), pcb->local_port));
00525 return ERR_OK;
00526 }
00540 err_t
00541 udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
00542 {
00543 struct udp_pcb *ipcb;
00544
00545 if(pcb->local_port == 0) {
00546 err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
00547 if(err != ERR_OK)
00548 return err;
00549 }
00550
00551 ip_addr_set(&pcb->remote_ip, ipaddr);
00552 pcb->remote_port = port;
00554 #if 0
00555 pcb->flags |= UDP_FLAGS_CONNECTED;
00556
00557 if(ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) {
00558 struct netif *netif;
00559
00560 if((netif = ip_route(&(pcb->remote_ip))) == NULL) {
00561 DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr));
00562 #ifdef UDP_STATS
00563 ++lwip_stats.udp.rterr;
00564 #endif
00565 return ERR_RTE;
00566 }
00570 pcb->local_ip = netif->ip_addr;
00571 } else if(ip_addr_isany(&pcb->remote_ip)) {
00572 pcb->local_ip.addr = 0;
00573 }
00574 #endif
00575 DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_connect: connected to %u.%u.%u.%u, port %u\n",
00576 (u8_t)(ntohl(pcb->remote_ip.addr) >> 24 & 0xff),
00577 (u8_t)(ntohl(pcb->remote_ip.addr) >> 16 & 0xff),
00578 (u8_t)(ntohl(pcb->remote_ip.addr) >> 8 & 0xff),
00579 (u8_t)(ntohl(pcb->remote_ip.addr) & 0xff), pcb->remote_port));
00580
00581
00582 for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) {
00583 if(pcb == ipcb) {
00584
00585 return ERR_OK;
00586 }
00587 }
00588
00589 pcb->next = udp_pcbs;
00590 udp_pcbs = pcb;
00591 return ERR_OK;
00592 }
00593
00594 void
00595 udp_disconnect(struct udp_pcb *pcb)
00596 {
00597 pcb->flags &= ~UDP_FLAGS_CONNECTED;
00598 }
00599
00600 void
00601 udp_recv(struct udp_pcb *pcb,
00602 void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p,
00603 struct ip_addr *addr, u16_t port),
00604 void *recv_arg)
00605 {
00606
00607 pcb->recv = recv;
00608 pcb->recv_arg = recv_arg;
00609 }
00618 void
00619 udp_remove(struct udp_pcb *pcb)
00620 {
00621 struct udp_pcb *pcb2;
00622
00623 if (udp_pcbs == pcb) {
00624
00625 udp_pcbs = udp_pcbs->next;
00626
00627 } else for(pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
00628
00629 if(pcb2->next != NULL && pcb2->next == pcb) {
00630
00631 pcb2->next = pcb->next;
00632 }
00633 }
00634 memp_free(MEMP_UDP_PCB, pcb);
00635 }
00644 struct udp_pcb *
00645 udp_new(void) {
00646 struct udp_pcb *pcb;
00647 pcb = memp_malloc(MEMP_UDP_PCB);
00648
00649 if(pcb != NULL) {
00650
00651 memset(pcb, 0, sizeof(struct udp_pcb));
00652 }
00653 return pcb;
00654 }
00655
00656 #if UDP_DEBUG
00657 int
00658 udp_debug_print(struct udp_hdr *udphdr)
00659 {
00660 DEBUGF(UDP_DEBUG, ("UDP header:\n"));
00661 DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
00662 DEBUGF(UDP_DEBUG, ("| %5u | %5u | (src port, dest port)\n",
00663 ntohs(udphdr->src), ntohs(udphdr->dest)));
00664 DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
00665 DEBUGF(UDP_DEBUG, ("| %5u | 0x%04x | (len, chksum)\n",
00666 ntohs(udphdr->len), ntohs(udphdr->chksum)));
00667 DEBUGF(UDP_DEBUG, ("+-------------------------------+\n"));
00668 return 0;
00669 }
00670 #endif
00671
00672 #endif
00673
00674
00675
00676
00677
00678
00679
00680
00681