Skip to content

Commit

Permalink
pkg: provide sock_ip support for lwip
Browse files Browse the repository at this point in the history
  • Loading branch information
miri64 committed Jan 16, 2017
1 parent e547ff1 commit f98418e
Show file tree
Hide file tree
Showing 16 changed files with 2,770 additions and 1 deletion.
9 changes: 9 additions & 0 deletions Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,14 @@ ifneq (,$(filter lwip_conn_udp,$(USEMODULE)))
USEMODULE += lwip_udp
endif

ifneq (,$(filter lwip_sock_%,$(USEMODULE)))
USEMODULE += lwip_sock
endif

ifneq (,$(filter lwip_sock_ip,$(USEMODULE)))
USEMODULE += lwip_raw
endif

ifneq (,$(filter lwip_%,$(USEMODULE)))
USEMODULE += lwip
endif
Expand All @@ -438,6 +446,7 @@ endif

ifneq (,$(filter lwip_contrib,$(USEMODULE)))
USEMODULE += sema
USEMODULE += xtimer
endif

ifneq (,$(filter sema,$(USEMODULE)))
Expand Down
9 changes: 9 additions & 0 deletions pkg/lwip/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,12 @@ endif
ifneq (,$(filter lwip_netdev2,$(USEMODULE)))
DIRS += $(RIOTBASE)/pkg/lwip/contrib/netdev2
endif
ifneq (,$(filter lwip_sock,$(USEMODULE)))
ifneq (,$(filter lwip_ipv6,$(USEMODULE)))
CFLAGS += -DSOCK_HAS_IPV6
endif
DIRS += $(RIOTBASE)/pkg/lwip/contrib/sock
endif
ifneq (,$(filter lwip_sock_ip,$(USEMODULE)))
DIRS += $(RIOTBASE)/pkg/lwip/contrib/sock/ip
endif
3 changes: 3 additions & 0 deletions pkg/lwip/contrib/sock/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
MODULE := lwip_sock

include $(RIOTBASE)/Makefile.base
3 changes: 3 additions & 0 deletions pkg/lwip/contrib/sock/ip/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
MODULE := lwip_sock_ip

include $(RIOTBASE)/Makefile.base
181 changes: 181 additions & 0 deletions pkg/lwip/contrib/sock/ip/lwip_sock_ip.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
/*
* Copyright (C) 2016 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @{
*
* @file
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/

#include <errno.h>

#include "net/ipv4/addr.h"
#include "net/ipv6/addr.h"
#include "net/ipv6/hdr.h"
#include "net/sock/ip.h"
#include "timex.h"

#include "lwip/api.h"
#include "lwip/ip4.h"
#include "lwip/ip6.h"
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/sock_internal.h"


int sock_ip_create(sock_ip_t *sock, const sock_ip_ep_t *local,
const sock_ip_ep_t *remote, uint8_t proto, uint16_t flags)
{
assert(sock != NULL);

int res;
struct netconn *tmp = NULL;

/* we pay attention in lwip_sock_create that _sock_tl_ep::port is not
* touched for RAW */
if ((res = lwip_sock_create(&tmp, (struct _sock_tl_ep *)local,
(struct _sock_tl_ep *)remote, proto, flags,
NETCONN_RAW)) == 0) {
sock->conn = tmp;
}
return res;
}

void sock_ip_close(sock_ip_t *sock)
{
assert(sock != NULL);
if (sock->conn != NULL) {
netconn_delete(sock->conn);
sock->conn = NULL;
}
}

int sock_ip_get_local(sock_ip_t *sock, sock_ip_ep_t *ep)
{
assert(sock != NULL);
return (lwip_sock_get_addr(sock->conn, (struct _sock_tl_ep *)ep,
1)) ? -EADDRNOTAVAIL : 0;
}

int sock_ip_get_remote(sock_ip_t *sock, sock_ip_ep_t *ep)
{
assert(sock != NULL);
return (lwip_sock_get_addr(sock->conn, (struct _sock_tl_ep *)ep,
0)) ? -ENOTCONN : 0;
}

#if LWIP_IPV4
static uint16_t _ip4_addr_to_netif(const ip4_addr_p_t *addr)
{
assert(addr != NULL);

if (!ip4_addr_isany(addr)) {
for (struct netif *netif = netif_list; netif != NULL; netif = netif->next) {
if (netif_ip4_addr(netif)->addr == addr->addr) {
return (int)netif->num + 1;
}
}
}
return SOCK_ADDR_ANY_NETIF;
}
#endif

#if LWIP_IPV6
static uint16_t _ip6_addr_to_netif(const ip6_addr_p_t *_addr)
{
ip6_addr_t addr;

assert(_addr != NULL);
ip6_addr_copy(addr, *_addr);
if (!ip6_addr_isany_val(addr)) {
for (struct netif *netif = netif_list; netif != NULL; netif = netif->next) {
if (netif_get_ip6_addr_match(netif, &addr) >= 0) {
return (int)netif->num + 1;
}
}
}
return SOCK_ADDR_ANY_NETIF;
}
#endif

static int _parse_iphdr(const struct netbuf *buf, void *data, size_t max_len,
sock_ip_ep_t *remote)
{
uint8_t *data_ptr = buf->p->payload;
size_t data_len = buf->p->len;

assert(buf->p->next == NULL); /* TODO this might not be generally the case
* check later with larger payloads */
switch (data_ptr[0] >> 4) {
#if LWIP_IPV4
case 4:
if ((data_len - sizeof(struct ip_hdr)) > max_len) {
return -ENOBUFS;
}
if (remote != NULL) {
struct ip_hdr *iphdr = (struct ip_hdr *)data_ptr;

assert(buf->p->len > sizeof(struct ip_hdr));
remote->family = AF_INET;
memcpy(&remote->addr, &iphdr->src, sizeof(ip4_addr_t));
remote->netif = _ip4_addr_to_netif(&iphdr->dest);
}
data_ptr += sizeof(struct ip_hdr);
data_len -= sizeof(struct ip_hdr);
break;
#endif
#if LWIP_IPV6
case 6:
if ((data_len - sizeof(struct ip6_hdr)) > max_len) {
return -ENOBUFS;
}
if (remote != NULL) {
struct ip6_hdr *iphdr = (struct ip6_hdr *)data_ptr;

assert(buf->p->len > sizeof(struct ip6_hdr));
remote->family = AF_INET6;
memcpy(&remote->addr, &iphdr->src, sizeof(ip6_addr_t));
remote->netif = _ip6_addr_to_netif(&iphdr->dest);
}
data_ptr += sizeof(struct ip6_hdr);
data_len -= sizeof(struct ip6_hdr);
break;
#endif
default:
return -EPROTO;
}
memcpy(data, data_ptr, data_len);
return (ssize_t)data_len;
}

ssize_t sock_ip_recv(sock_ip_t *sock, void *data, size_t max_len,
uint32_t timeout, sock_ip_ep_t *remote)
{
struct netbuf *buf;
int res;

assert((sock != NULL) && (data != NULL) && (max_len > 0));
if ((res = lwip_sock_recv(sock->conn, timeout, &buf)) < 0) {
return res;
}
res = _parse_iphdr(buf, data, max_len, remote);
netbuf_delete(buf);
return res;
}

ssize_t sock_ip_send(sock_ip_t *sock, const void *data, size_t len,
uint8_t proto, const sock_ip_ep_t *remote)
{
assert((sock != NULL) || (remote != NULL));
assert((len == 0) || (data != NULL)); /* (len != 0) => (data != NULL) */
return lwip_sock_send(&sock->conn, data, len, proto,
(struct _sock_tl_ep *)remote, NETCONN_RAW);
}

/** @} */
Loading

0 comments on commit f98418e

Please sign in to comment.