449 |
{ |
{ |
450 |
struct udp_pcb *ipcb; |
struct udp_pcb *ipcb; |
451 |
u8_t rebind; |
u8_t rebind; |
452 |
|
DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_bind(ipaddr = %lx, port = %u)\n", ipaddr->addr, port)); |
453 |
rebind = 0; |
rebind = 0; |
454 |
/* Check for double bind and rebind of the same pcb */ |
/* Check for double bind and rebind of the same pcb */ |
455 |
for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { |
for(ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { |
456 |
/* is this UDP PCB already on active list? */ |
/* is this UDP PCB already on active list? */ |
457 |
if (pcb == ipcb) { |
if (pcb == ipcb) { |
458 |
/* TODO: add assert that rebind is 0 here (pcb may |
/* pcb may occur at most once in active list */ |
459 |
occur at most once in list) */ |
LWIP_ASSERT("rebind == 0", rebind == 0); |
460 |
|
/* pcb already in list, just rebind */ |
461 |
rebind = 1; |
rebind = 1; |
462 |
} |
} |
463 |
/* this code does not allow upper layer to share a UDP port for |
/* this code does not allow upper layer to share a UDP port for |
479 |
} |
} |
480 |
/* bind local address */ |
/* bind local address */ |
481 |
ip_addr_set(&pcb->local_ip, ipaddr); |
ip_addr_set(&pcb->local_ip, ipaddr); |
482 |
|
/* no port specified? */ |
483 |
if (port == 0) { |
if (port == 0) { |
484 |
#ifndef UDP_LOCAL_PORT_RANGE_START |
#ifndef UDP_LOCAL_PORT_RANGE_START |
485 |
#define UDP_LOCAL_PORT_RANGE_START 4096 |
#define UDP_LOCAL_PORT_RANGE_START 4096 |
487 |
#endif |
#endif |
488 |
port = UDP_LOCAL_PORT_RANGE_START; |
port = UDP_LOCAL_PORT_RANGE_START; |
489 |
ipcb = udp_pcbs; |
ipcb = udp_pcbs; |
490 |
while((ipcb != NULL) && (port != UDP_LOCAL_PORT_RANGE_END)) { |
while ((ipcb != NULL) && (port != UDP_LOCAL_PORT_RANGE_END)) { |
491 |
if(ipcb->local_port == port) { |
if (ipcb->local_port == port) { |
492 |
port++; |
port++; |
493 |
ipcb = udp_pcbs; |
ipcb = udp_pcbs; |
494 |
} else |
} else |
495 |
ipcb = ipcb->next; |
ipcb = ipcb->next; |
496 |
} |
} |
497 |
if(ipcb) { |
if (ipcb != NULL) { |
498 |
/* no more ports available in local range */ |
/* no more ports available in local range */ |
499 |
DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n")); |
DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n")); |
500 |
return ERR_USE; |
return ERR_USE; |
501 |
} |
} |
502 |
} |
} |
503 |
pcb->local_port = port; |
pcb->local_port = port; |
504 |
/* We need to place the PCB on the list if not already there. */ |
/* pcb not active yet? */ |
505 |
if (rebind == 0) { |
if (rebind == 0) { |
506 |
|
/* place the PCB on the active list if not already there */ |
507 |
pcb->next = udp_pcbs; |
pcb->next = udp_pcbs; |
508 |
udp_pcbs = pcb; |
udp_pcbs = pcb; |
509 |
} |
} |
510 |
DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_bind: bound to %u.%u.%u.%u, port %u\n", |
DEBUGF(UDP_DEBUG | DBG_TRACE | DBG_STATE, ("udp_bind: bound to %u.%u.%u.%u, port %u\n", |
511 |
(u8_t)(ntohl(ipaddr->addr) >> 24 & 0xff), |
(u8_t)(ntohl(ipaddr->addr) >> 24 & 0xff), |
512 |
(u8_t)(ntohl(ipaddr->addr) >> 16 & 0xff), |
(u8_t)(ntohl(ipaddr->addr) >> 16 & 0xff), |
513 |
(u8_t)(ntohl(ipaddr->addr) >> 8 & 0xff), |
(u8_t)(ntohl(ipaddr->addr) >> 8 & 0xff), |
514 |
(u8_t)(ntohl(ipaddr->addr) & 0xff), port)); |
(u8_t)(ntohl(ipaddr->addr) & 0xff), port)); |
515 |
return ERR_OK; |
return ERR_OK; |
516 |
} |
} |
517 |
/** |
/** |