93 |
u16_t src, dest; |
u16_t src, dest; |
94 |
|
|
95 |
PERF_START; |
PERF_START; |
96 |
|
(void)inp; |
97 |
|
|
98 |
udphdr = (struct udp_hdr *)(u8_t *)iphdr + IPH_HL(iphdr) * 4; |
udphdr = (struct udp_hdr *)(u8_t *)iphdr + IPH_HL(iphdr) * 4; |
99 |
|
|
178 |
|
|
179 |
udphdr = (struct udp_hdr *)((u8_t *)p->payload - UDP_HLEN); |
udphdr = (struct udp_hdr *)((u8_t *)p->payload - UDP_HLEN); |
180 |
|
|
181 |
DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %d\n", p->tot_len)); |
DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %u\n", p->tot_len)); |
182 |
|
|
183 |
src = NTOHS(udphdr->src); |
src = NTOHS(udphdr->src); |
184 |
dest = NTOHS(udphdr->dest); |
dest = NTOHS(udphdr->dest); |
342 |
err_t err; |
err_t err; |
343 |
struct pbuf *hdr; |
struct pbuf *hdr; |
344 |
|
|
345 |
DEBUGF(UDP_DEBUG, ("udp_send")); |
DEBUGF(UDP_DEBUG, ("udp_send\n")); |
346 |
|
|
347 |
|
if(pcb->local_port == 0) { |
348 |
|
err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); |
349 |
|
if(err != ERR_OK) |
350 |
|
return err; |
351 |
|
} |
352 |
|
|
353 |
/* hdr will point to the UDP header pbuf if an extra header pbuf has |
/* hdr will point to the UDP header pbuf if an extra header pbuf has |
354 |
to be allocated. */ |
to be allocated. */ |
355 |
hdr = NULL; |
hdr = NULL; |
367 |
/* have p point to header pbuf */ |
/* have p point to header pbuf */ |
368 |
p = hdr; |
p = hdr; |
369 |
} |
} |
370 |
DEBUGF(UDP_DEBUG, ("udp_send: got pbuf")); |
DEBUGF(UDP_DEBUG, ("udp_send: got pbuf\n")); |
371 |
|
|
372 |
udphdr = p->payload; |
udphdr = p->payload; |
373 |
udphdr->src = htons(pcb->local_port); |
udphdr->src = htons(pcb->local_port); |
390 |
src_ip = &(pcb->local_ip); |
src_ip = &(pcb->local_ip); |
391 |
} |
} |
392 |
|
|
393 |
DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %d\n", p->tot_len)); |
DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %u\n", p->tot_len)); |
394 |
|
|
395 |
/* UDP Lite protocol? */ |
/* UDP Lite protocol? */ |
396 |
if(pcb->flags & UDP_FLAGS_UDPLITE) { |
if(pcb->flags & UDP_FLAGS_UDPLITE) { |
397 |
DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %u", p->tot_len)); |
DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %u\n", p->tot_len)); |
398 |
/* set UDP message length in UDP header */ |
/* set UDP message length in UDP header */ |
399 |
udphdr->len = htons(pcb->chksum_len); |
udphdr->len = htons(pcb->chksum_len); |
400 |
/* calculate checksum */ |
/* calculate checksum */ |
408 |
snmp_inc_udpoutdatagrams(); |
snmp_inc_udpoutdatagrams(); |
409 |
#endif |
#endif |
410 |
} else { |
} else { |
411 |
DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %u", p->tot_len)); |
DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %u\n", p->tot_len)); |
412 |
udphdr->len = htons(p->tot_len); |
udphdr->len = htons(p->tot_len); |
413 |
/* calculate checksum */ |
/* calculate checksum */ |
414 |
if((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { |
if((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { |
416 |
/* chksum zero must become 0xffff, as zero means 'no checksum' */ |
/* chksum zero must become 0xffff, as zero means 'no checksum' */ |
417 |
if(udphdr->chksum == 0x0000) udphdr->chksum = 0xffff; |
if(udphdr->chksum == 0x0000) udphdr->chksum = 0xffff; |
418 |
} |
} |
419 |
DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum %x", udphdr->chksum)); |
DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum %x\n", udphdr->chksum)); |
420 |
#if LWIP_SNMP > 0 |
#if LWIP_SNMP > 0 |
421 |
snmp_inc_udpoutdatagrams(); |
snmp_inc_udpoutdatagrams(); |
422 |
#endif |
#endif |
423 |
DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if(,,,,IP_PROTO_UDP,)")); |
DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if(,,,,IP_PROTO_UDP,)\n")); |
424 |
/* output to IP */ |
/* output to IP */ |
425 |
err = ip_output_if(p, src_ip, &pcb->remote_ip, UDP_TTL, IP_PROTO_UDP, netif); |
err = ip_output_if(p, src_ip, &pcb->remote_ip, UDP_TTL, IP_PROTO_UDP, netif); |
426 |
} |
} |
474 |
} |
} |
475 |
/* bind local address */ |
/* bind local address */ |
476 |
ip_addr_set(&pcb->local_ip, ipaddr); |
ip_addr_set(&pcb->local_ip, ipaddr); |
477 |
|
if(port == 0) { |
478 |
|
#ifndef UDP_LOCAL_PORT_RANGE_START |
479 |
|
#define UDP_LOCAL_PORT_RANGE_START 4096 |
480 |
|
#define UDP_LOCAL_PORT_RANGE_END 0x7fff |
481 |
|
#endif |
482 |
|
port = UDP_LOCAL_PORT_RANGE_START; |
483 |
|
ipcb = udp_pcbs; |
484 |
|
while((ipcb != NULL) && (port != UDP_LOCAL_PORT_RANGE_END)) { |
485 |
|
if(ipcb->local_port == port) { |
486 |
|
port++; |
487 |
|
ipcb = udp_pcbs; |
488 |
|
} else |
489 |
|
ipcb = ipcb->next; |
490 |
|
} |
491 |
|
if(ipcb) /* no more ports available in local range */ |
492 |
|
return ERR_USE; |
493 |
|
} |
494 |
pcb->local_port = port; |
pcb->local_port = port; |
495 |
|
|
496 |
/* We need to place the PCB on the list if not already there. */ |
/* We need to place the PCB on the list if not already there. */ |
499 |
udp_pcbs = pcb; |
udp_pcbs = pcb; |
500 |
} |
} |
501 |
|
|
502 |
DEBUGF(UDP_DEBUG, ("udp_bind: bound to port %d\n", port)); |
DEBUGF(UDP_DEBUG, ("udp_bind: bound to port %u\n", port)); |
503 |
return ERR_OK; |
return ERR_OK; |
504 |
} |
} |
505 |
/** |
/** |
517 |
udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port) |
udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port) |
518 |
{ |
{ |
519 |
struct udp_pcb *ipcb; |
struct udp_pcb *ipcb; |
520 |
|
|
521 |
|
if(pcb->local_port == 0) { |
522 |
|
err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); |
523 |
|
if(err != ERR_OK) |
524 |
|
return err; |
525 |
|
} |
526 |
|
|
527 |
ip_addr_set(&pcb->remote_ip, ipaddr); |
ip_addr_set(&pcb->remote_ip, ipaddr); |
528 |
pcb->remote_port = port; |
pcb->remote_port = port; |
529 |
pcb->flags |= UDP_FLAGS_CONNECTED; |
pcb->flags |= UDP_FLAGS_CONNECTED; |
530 |
|
|
531 |
|
/* Nail down local IP for netconn_addr()/getsockname() */ |
532 |
|
if(ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) { |
533 |
|
struct netif *netif; |
534 |
|
|
535 |
|
if((netif = ip_route(&(pcb->remote_ip))) == NULL) { |
536 |
|
DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr)); |
537 |
|
#ifdef UDP_STATS |
538 |
|
++lwip_stats.udp.rterr; |
539 |
|
#endif /* UDP_STATS */ |
540 |
|
return ERR_RTE; |
541 |
|
} |
542 |
|
|
543 |
|
pcb->local_ip = netif->ip_addr; |
544 |
|
} else if(ip_addr_isany(&pcb->remote_ip)) { |
545 |
|
pcb->local_ip.addr = 0; |
546 |
|
} |
547 |
|
|
548 |
/* Insert UDP PCB into the list of active UDP PCBs. */ |
/* Insert UDP PCB into the list of active UDP PCBs. */ |
549 |
for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { |
for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { |
550 |
if(pcb == ipcb) { |
if(pcb == ipcb) { |
626 |
{ |
{ |
627 |
DEBUGF(UDP_DEBUG, ("UDP header:\n")); |
DEBUGF(UDP_DEBUG, ("UDP header:\n")); |
628 |
DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); |
DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); |
629 |
DEBUGF(UDP_DEBUG, ("| %5d | %5d | (src port, dest port)\n", |
DEBUGF(UDP_DEBUG, ("| %5u | %5u | (src port, dest port)\n", |
630 |
ntohs(udphdr->src), ntohs(udphdr->dest))); |
ntohs(udphdr->src), ntohs(udphdr->dest))); |
631 |
DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); |
DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); |
632 |
DEBUGF(UDP_DEBUG, ("| %5d | 0x%04x | (len, chksum)\n", |
DEBUGF(UDP_DEBUG, ("| %5u | 0x%04x | (len, chksum)\n", |
633 |
ntohs(udphdr->len), ntohs(udphdr->chksum))); |
ntohs(udphdr->len), ntohs(udphdr->chksum))); |
634 |
DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); |
DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); |
635 |
return 0; |
return 0; |