mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-03-24 04:43:39 +00:00
Implemented new function udp_sendto_if which takes the netif to send as an argument (to be able to send on netifs that are down).
This commit is contained in:
parent
3874f5f5e8
commit
b4741332e0
@ -499,6 +499,10 @@ HISTORY
|
||||
|
||||
++ Bug fixes:
|
||||
|
||||
2007-11-27 Simon Goldschmidt
|
||||
* udp.h, udp.c, dhcp.c: Implemented new function udp_sendto_if which takes the
|
||||
netif to send as an argument (to be able to send on netifs that are down).
|
||||
|
||||
2007-11-26 Simon Goldschmidt
|
||||
* tcp_in.c: Fixed bug #21582: pcb->acked accounting can be wrong when ACKs
|
||||
arrive out-of-order
|
||||
|
@ -269,10 +269,8 @@ dhcp_select(struct netif *netif)
|
||||
|
||||
/* TODO: we really should bind to a specific local interface here
|
||||
but we cannot specify an unconfigured netif as it is addressless */
|
||||
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
|
||||
/* send broadcast to any DHCP server */
|
||||
udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
|
||||
udp_send(dhcp->pcb, dhcp->p_out);
|
||||
udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
|
||||
/* reconnect to any (or to server here?!) */
|
||||
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
|
||||
dhcp_delete_request(netif);
|
||||
@ -589,6 +587,11 @@ dhcp_start(struct netif *netif)
|
||||
netif->dhcp = dhcp = NULL;
|
||||
return ERR_MEM;
|
||||
}
|
||||
/* set up local and remote port for the pcb */
|
||||
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
|
||||
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
|
||||
/* set up the recv callback and argument */
|
||||
udp_recv(dhcp->pcb, dhcp_recv, netif);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n"));
|
||||
/* (re)start the DHCP negotiation */
|
||||
result = dhcp_discover(netif);
|
||||
@ -613,7 +616,7 @@ dhcp_start(struct netif *netif)
|
||||
void
|
||||
dhcp_inform(struct netif *netif)
|
||||
{
|
||||
struct dhcp *dhcp;
|
||||
struct dhcp *dhcp, *old_dhcp = netif->dhcp;
|
||||
err_t result = ERR_OK;
|
||||
dhcp = mem_malloc(sizeof(struct dhcp));
|
||||
if (dhcp == NULL) {
|
||||
@ -649,7 +652,7 @@ dhcp_inform(struct netif *netif)
|
||||
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
|
||||
udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_inform: INFORMING\n"));
|
||||
udp_send(dhcp->pcb, dhcp->p_out);
|
||||
udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
|
||||
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
|
||||
dhcp_delete_request(netif);
|
||||
} else {
|
||||
@ -662,7 +665,7 @@ dhcp_inform(struct netif *netif)
|
||||
}
|
||||
dhcp->pcb = NULL;
|
||||
mem_free((void *)dhcp);
|
||||
netif->dhcp = NULL;
|
||||
netif->dhcp = old_dhcp;
|
||||
}
|
||||
}
|
||||
|
||||
@ -723,11 +726,10 @@ dhcp_decline(struct netif *netif)
|
||||
/* resize pbuf to reflect true size of options */
|
||||
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
|
||||
|
||||
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
|
||||
/* @todo: should we really connect here? we are performing sendto() */
|
||||
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
|
||||
/* per section 4.4.4, broadcast DECLINE messages */
|
||||
udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
|
||||
udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
|
||||
dhcp_delete_request(netif);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_decline: BACKING OFF\n"));
|
||||
} else {
|
||||
@ -776,12 +778,9 @@ dhcp_discover(struct netif *netif)
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: realloc()ing\n"));
|
||||
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
|
||||
|
||||
/* set receive callback function with netif as user data */
|
||||
udp_recv(dhcp->pcb, dhcp_recv, netif);
|
||||
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
|
||||
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n"));
|
||||
udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
|
||||
udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n"));
|
||||
dhcp_delete_request(netif);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n"));
|
||||
@ -924,9 +923,8 @@ dhcp_renew(struct netif *netif)
|
||||
|
||||
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
|
||||
|
||||
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
|
||||
udp_connect(dhcp->pcb, &dhcp->server_ip_addr, DHCP_SERVER_PORT);
|
||||
udp_send(dhcp->pcb, dhcp->p_out);
|
||||
udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif);
|
||||
dhcp_delete_request(netif);
|
||||
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew: RENEWING\n"));
|
||||
@ -977,11 +975,9 @@ dhcp_rebind(struct netif *netif)
|
||||
|
||||
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
|
||||
|
||||
/* set remote IP association to any DHCP server */
|
||||
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
|
||||
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
|
||||
/* broadcast to server */
|
||||
udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
|
||||
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
|
||||
udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif);
|
||||
dhcp_delete_request(netif);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n"));
|
||||
} else {
|
||||
@ -1026,9 +1022,8 @@ dhcp_release(struct netif *netif)
|
||||
|
||||
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
|
||||
|
||||
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
|
||||
udp_connect(dhcp->pcb, &dhcp->server_ip_addr, DHCP_SERVER_PORT);
|
||||
udp_send(dhcp->pcb, dhcp->p_out);
|
||||
udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif);
|
||||
dhcp_delete_request(netif);
|
||||
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n"));
|
||||
} else {
|
||||
|
134
src/core/udp.c
134
src/core/udp.c
@ -273,45 +273,6 @@ end:
|
||||
PERF_STOP("udp_input");
|
||||
}
|
||||
|
||||
/**
|
||||
* Send data to a specified address using UDP.
|
||||
*
|
||||
* @param pcb UDP PCB used to send the data.
|
||||
* @param p chain of pbuf's to be sent.
|
||||
* @param dst_ip Destination IP address.
|
||||
* @param dst_port Destination UDP port.
|
||||
*
|
||||
* dst_ip & dst_port are expected to be in the same byte order as in the pcb.
|
||||
*
|
||||
* If the PCB already has a remote address association, it will
|
||||
* be restored after the data is sent.
|
||||
*
|
||||
* @return lwIP error code (@see udp_send for possible error codes)
|
||||
*
|
||||
* @see udp_disconnect() udp_send()
|
||||
*/
|
||||
err_t
|
||||
udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
|
||||
struct ip_addr *dst_ip, u16_t dst_port)
|
||||
{
|
||||
err_t err;
|
||||
/* temporary space for current PCB remote address */
|
||||
struct ip_addr pcb_remote_ip;
|
||||
u16_t pcb_remote_port;
|
||||
/* remember current remote peer address of PCB */
|
||||
pcb_remote_ip.addr = pcb->remote_ip.addr;
|
||||
pcb_remote_port = pcb->remote_port;
|
||||
/* copy packet destination address to PCB remote peer address */
|
||||
pcb->remote_ip.addr = dst_ip->addr;
|
||||
pcb->remote_port = dst_port;
|
||||
/* send to the packet destination address */
|
||||
err = udp_send(pcb, p);
|
||||
/* restore PCB remote peer address */
|
||||
pcb->remote_ip.addr = pcb_remote_ip.addr;
|
||||
pcb->remote_port = pcb_remote_port;
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send data using UDP.
|
||||
*
|
||||
@ -333,14 +294,79 @@ udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
|
||||
err_t
|
||||
udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
{
|
||||
struct udp_hdr *udphdr;
|
||||
/* send to the packet using remote ip and port stored in the pcb */
|
||||
return udp_sendto(pcb, p, &pcb->remote_ip, pcb->remote_port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send data to a specified address using UDP.
|
||||
*
|
||||
* @param pcb UDP PCB used to send the data.
|
||||
* @param p chain of pbuf's to be sent.
|
||||
* @param dst_ip Destination IP address.
|
||||
* @param dst_port Destination UDP port.
|
||||
*
|
||||
* dst_ip & dst_port are expected to be in the same byte order as in the pcb.
|
||||
*
|
||||
* If the PCB already has a remote address association, it will
|
||||
* be restored after the data is sent.
|
||||
*
|
||||
* @return lwIP error code (@see udp_send for possible error codes)
|
||||
*
|
||||
* @see udp_disconnect() udp_send()
|
||||
*/
|
||||
err_t
|
||||
udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
|
||||
struct ip_addr *dst_ip, u16_t dst_port)
|
||||
{
|
||||
struct netif *netif;
|
||||
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | 3, ("udp_send\n"));
|
||||
|
||||
/* find the outgoing network interface for this packet */
|
||||
#if LWIP_IGMP
|
||||
netif = ip_route((ip_addr_ismulticast(dst_ip))?(&(pcb->multicast_ip)):(dst_ip));
|
||||
#else
|
||||
netif = ip_route(dst_ip);
|
||||
#endif /* LWIP_IGMP */
|
||||
|
||||
/* no outgoing network interface could be found? */
|
||||
if (netif == NULL) {
|
||||
LWIP_DEBUGF(UDP_DEBUG | 1, ("udp_send: No route to 0x%"X32_F"\n", dst_ip->addr));
|
||||
UDP_STATS_INC(udp.rterr);
|
||||
return ERR_RTE;
|
||||
}
|
||||
return udp_sendto_if(pcb, p, dst_ip, dst_port, netif);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send data to a specified address using UDP.
|
||||
* The netif used for sending can be specified.
|
||||
*
|
||||
* This function exists mainly for DHCP, to be able to send UDP packets
|
||||
* on a netif that is still down.
|
||||
*
|
||||
* @param pcb UDP PCB used to send the data.
|
||||
* @param p chain of pbuf's to be sent.
|
||||
* @param dst_ip Destination IP address.
|
||||
* @param dst_port Destination UDP port.
|
||||
* @param netif the netif used for sending.
|
||||
*
|
||||
* dst_ip & dst_port are expected to be in the same byte order as in the pcb.
|
||||
*
|
||||
* @return lwIP error code (@see udp_send for possible error codes)
|
||||
*
|
||||
* @see udp_disconnect() udp_send()
|
||||
*/
|
||||
err_t
|
||||
udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p,
|
||||
struct ip_addr *dst_ip, u16_t dst_port, struct netif *netif)
|
||||
{
|
||||
struct udp_hdr *udphdr;
|
||||
struct ip_addr *src_ip;
|
||||
err_t err;
|
||||
struct pbuf *q; /* q will be sent down the stack */
|
||||
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | 3, ("udp_send\n"));
|
||||
|
||||
/* if the PCB is not yet bound to a port, bind it here */
|
||||
if (pcb->local_port == 0) {
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | 2, ("udp_send: not yet bound to a port, binding now\n"));
|
||||
@ -351,20 +377,6 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
}
|
||||
}
|
||||
|
||||
/* find the outgoing network interface for this packet */
|
||||
#if LWIP_IGMP
|
||||
netif = ip_route((ip_addr_ismulticast(&(pcb->remote_ip)))?(&(pcb->multicast_ip)):(&(pcb->remote_ip)));
|
||||
#else
|
||||
netif = ip_route(&(pcb->remote_ip));
|
||||
#endif /* LWIP_IGMP */
|
||||
|
||||
/* no outgoing network interface could be found? */
|
||||
if (netif == NULL) {
|
||||
LWIP_DEBUGF(UDP_DEBUG | 1, ("udp_send: No route to 0x%"X32_F"\n", pcb->remote_ip.addr));
|
||||
UDP_STATS_INC(udp.rterr);
|
||||
return ERR_RTE;
|
||||
}
|
||||
|
||||
/* not enough space to add an UDP header to first pbuf in given p chain? */
|
||||
if (pbuf_header(p, UDP_HLEN)) {
|
||||
/* allocate header in a seperate new pbuf */
|
||||
@ -390,7 +402,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
/* q now represents the packet to be sent */
|
||||
udphdr = q->payload;
|
||||
udphdr->src = htons(pcb->local_port);
|
||||
udphdr->dest = htons(pcb->remote_port);
|
||||
udphdr->dest = htons(dst_port);
|
||||
/* in UDP, 0 checksum means 'no checksum' */
|
||||
udphdr->chksum = 0x0000;
|
||||
|
||||
@ -440,7 +452,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
udphdr->len = htons(chklen_hdr);
|
||||
/* calculate checksum */
|
||||
#if CHECKSUM_GEN_UDP
|
||||
udphdr->chksum = inet_chksum_pseudo_partial(q, src_ip, &(pcb->remote_ip),
|
||||
udphdr->chksum = inet_chksum_pseudo_partial(q, src_ip, dst_ip,
|
||||
IP_PROTO_UDPLITE, q->tot_len, chklen);
|
||||
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
||||
if (udphdr->chksum == 0x0000)
|
||||
@ -451,7 +463,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = &(pcb->addr_hint);
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);
|
||||
err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = NULL;
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
@ -463,7 +475,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
/* calculate checksum */
|
||||
#if CHECKSUM_GEN_UDP
|
||||
if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) {
|
||||
udphdr->chksum = inet_chksum_pseudo(q, src_ip, &pcb->remote_ip, IP_PROTO_UDP, q->tot_len);
|
||||
udphdr->chksum = inet_chksum_pseudo(q, src_ip, dst_ip, IP_PROTO_UDP, q->tot_len);
|
||||
/* chksum zero must become 0xffff, as zero means 'no checksum' */
|
||||
if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
|
||||
}
|
||||
@ -474,7 +486,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = &(pcb->addr_hint);
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);
|
||||
err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
netif->addr_hint = NULL;
|
||||
#endif /* LWIP_NETIF_HWADDRHINT*/
|
||||
|
@ -123,6 +123,7 @@ void udp_recv (struct udp_pcb *pcb,
|
||||
struct ip_addr *addr,
|
||||
u16_t port),
|
||||
void *recv_arg);
|
||||
err_t udp_sendto_if (struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *dst_ip, u16_t dst_port, struct netif *netif);
|
||||
err_t udp_sendto (struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *dst_ip, u16_t dst_port);
|
||||
err_t udp_send (struct udp_pcb *pcb, struct pbuf *p);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user