pkg/lwip: Implement sock_aux_local

Provide address the IP packet / UDP datagram was received on in the auxiliary
data, if module sock_aux_local is used.
This commit is contained in:
Marian Buschsieweke 2020-07-27 21:47:37 +02:00
parent 9d46bc7d7f
commit 77b39c5550
No known key found for this signature in database
GPG Key ID: 61F64C6599B1539F
3 changed files with 56 additions and 18 deletions

View File

@ -108,7 +108,7 @@ static uint16_t _ip6_addr_to_netif(const ip6_addr_p_t *_addr)
#endif
static int _parse_iphdr(struct netbuf *buf, void **data, void **ctx,
sock_ip_ep_t *remote)
sock_ip_ep_t *remote, sock_ip_ep_t *local)
{
uint8_t *data_ptr = buf->ptr->payload;
size_t data_len = buf->ptr->len;
@ -124,6 +124,13 @@ static int _parse_iphdr(struct netbuf *buf, void **data, void **ctx,
memcpy(&remote->addr, &iphdr->src, sizeof(ip4_addr_t));
remote->netif = _ip4_addr_to_netif(&iphdr->dest);
}
if (local != NULL) {
struct ip_hdr *iphdr = (struct ip_hdr *)data_ptr;
assert(buf->p->len > sizeof(struct ip_hdr));
local->family = AF_INET;
memcpy(&local->addr, &iphdr->dest, sizeof(ip4_addr_t));
}
data_ptr += sizeof(struct ip_hdr);
data_len -= sizeof(struct ip_hdr);
break;
@ -138,6 +145,13 @@ static int _parse_iphdr(struct netbuf *buf, void **data, void **ctx,
memcpy(&remote->addr, &iphdr->src, sizeof(ip6_addr_t));
remote->netif = _ip6_addr_to_netif(&iphdr->dest);
}
if (local != NULL) {
struct ip6_hdr *iphdr = (struct ip6_hdr *)data_ptr;
assert(buf->p->len > sizeof(struct ip6_hdr));
local->family = AF_INET6;
memcpy(&local->addr, &iphdr->dest, sizeof(ip6_addr_t));
}
data_ptr += sizeof(struct ip6_hdr);
data_len -= sizeof(struct ip6_hdr);
break;
@ -202,7 +216,14 @@ ssize_t sock_ip_recv_buf_aux(sock_ip_t *sock, void **data, void **ctx,
if ((res = lwip_sock_recv(sock->base.conn, timeout, &buf)) < 0) {
return res;
}
res = _parse_iphdr(buf, data, ctx, remote);
sock_ip_ep_t *local = NULL;
#if IS_USED(MODULE_SOCK_AUX_LOCAL)
if (aux != NULL) {
local = &aux->local;
aux->flags &= ~(SOCK_AUX_GET_LOCAL);
}
#endif
res = _parse_iphdr(buf, data, ctx, remote, local);
return res;
}

View File

@ -23,8 +23,9 @@
#include "lwip/api.h"
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/sock_internal.h"
#include "lwip/sys.h"
#include "lwip/udp.h"
int sock_udp_create(sock_udp_t *sock, const sock_udp_ep_t *local,
const sock_udp_ep_t *remote, uint16_t flags)
@ -121,29 +122,41 @@ ssize_t sock_udp_recv_buf_aux(sock_udp_t *sock, void **data, void **ctx,
if ((res = lwip_sock_recv(sock->base.conn, timeout, &buf)) < 0) {
return res;
}
if (remote != NULL) {
if ((remote != NULL) ||
((aux != NULL) && IS_USED(MODULE_SOCK_AUX_LOCAL)
&& IS_ACTIVE(LWIP_NETBUF_RECVINFO))) {
/* convert remote */
size_t addr_len;
size_t addr_len = sizeof(ipv4_addr_t);
int family = AF_INET;
if (NETCONNTYPE_ISIPV6(sock->base.conn->type)) {
addr_len = sizeof(ipv6_addr_t);
remote->family = AF_INET6;
family = AF_INET6;
}
else if (IS_ACTIVE(LWIP_IPV4)) {
addr_len = sizeof(ipv4_addr_t);
remote->family = AF_INET;
}
else {
else if (!IS_ACTIVE(LWIP_IPV4)) {
netbuf_delete(buf);
return -EPROTO;
}
if (remote != NULL) {
remote->family = family;
#if LWIP_NETBUF_RECVINFO
remote->netif = lwip_sock_bind_addr_to_netif(&buf->toaddr);
remote->netif = lwip_sock_bind_addr_to_netif(&buf->toaddr);
#else
remote->netif = SOCK_ADDR_ANY_NETIF;
remote->netif = SOCK_ADDR_ANY_NETIF;
#endif
/* copy address */
memcpy(&remote->addr, &buf->addr, addr_len);
remote->port = buf->port;
/* copy address */
memcpy(&remote->addr, &buf->addr, addr_len);
remote->port = buf->port;
}
#if IS_USED(MODULE_SOCK_AUX_LOCAL)
static_assert(IS_ACTIVE(LWIP_NETBUF_RECVINFO),
"sock_aux_local depends on LWIP_NETBUF_RECVINFO");
if ((aux != NULL) && (aux->flags & SOCK_AUX_GET_LOCAL)) {
aux->flags &= ~(SOCK_AUX_GET_LOCAL);
aux->local.family = family;
memcpy(&aux->local.addr, &buf->toaddr, addr_len);
aux->local.port = sock->base.conn->pcb.udp->local_port;
}
#endif /* MODULE_SOCK_AUX_LOCAL */
}
*data = buf->ptr->payload;
*ctx = buf;

View File

@ -128,11 +128,15 @@ extern "C" {
#define LWIP_UDPLITE 0
#endif /* MODULE_LWIP_UDPLITE */
#if defined(MODULE_LWIP_SOCK)
#if IS_USED(MODULE_LWIP_SOCK)
#define LWIP_NETCONN 1
#if IS_USED(MODULE_SOCK_AUX_LOCAL)
#define LWIP_NETBUF_RECVINFO 1
#endif /* MODULE_SOCK_AUX_LOCAL */
#else
#define LWIP_NETCONN 0
#endif
#endif /* MODULE_LWIP_SOCK */
#ifndef TCP_LISTEN_BACKLOG
# if defined(MODULE_LWIP_SOCK_TCP)