Combined IPv4 and IPv6 code where possible, added defines to access IPv4/IPv6 in non-IP code so that the code is more readable.

This commit is contained in:
goldsimon
2011-05-25 17:16:35 +00:00
parent 9546e65617
commit 6865806b55
41 changed files with 1392 additions and 2269 deletions

View File

@@ -58,15 +58,65 @@
#include <string.h>
/* Check that the family member of a struct sockaddr matches the socket's IP version */
#define IP4ADDR_PORT_TO_SOCKADDR(sin, ipXaddr, port) do { \
(sin)->sin_len = sizeof(struct sockaddr_in); \
(sin)->sin_family = AF_INET; \
(sin)->sin_port = htons((port)); \
inet_addr_from_ipaddr(&(sin)->sin_addr, ipX_2_ip(ipXaddr)); \
memset((sin)->sin_zero, 0, SIN_ZERO_LEN); }while(0)
#define SOCKADDR4_TO_IP4ADDR_PORT(sin, ipXaddr, port) do { \
inet_addr_to_ipaddr(ipX_2_ip(ipXaddr), &((sin)->sin_addr)); \
(port) = (sin)->sin_port; }while(0)
#if LWIP_IPV6
#define SOCK_ADDR_MATCH(name, sock) \
#define IS_SOCK_ADDR_LEN_VALID(namelen) (((namelen) == sizeof(struct sockaddr_in)) || \
((namelen) == sizeof(struct sockaddr_in6)))
#define IS_SOCK_ADDR_TYPE_VALID(name) (((name)->sa_family == AF_INET) || \
((name)->sa_family == AF_INET6))
#define SOCK_ADDR_TYPE_MATCH(name, sock) \
((((name)->sa_family == AF_INET) && !(NETCONNTYPE_ISIPV6((sock)->conn->type))) || \
(((name)->sa_family == AF_INET6) && (NETCONNTYPE_ISIPV6((sock)->conn->type))))
#define IP6ADDR_PORT_TO_SOCKADDR(sin6, ipXaddr, port) do { \
(sin6)->sin6_len = sizeof(struct sockaddr_in6); \
(sin6)->sin6_family = AF_INET6; \
(sin6)->sin6_port = htons((port)); \
(sin6)->sin6_flowinfo = 0; \
inet6_addr_from_ip6addr(&(sin6)->sin6_addr, ipX_2_ip6(ipXaddr)); }while(0)
#define IPXADDR_PORT_TO_SOCKADDR(isipv6, sockaddr, ipXaddr, port) do { \
if (isipv6) { \
IP6ADDR_PORT_TO_SOCKADDR(((struct sockaddr_in6*)(sockaddr)), ipXaddr, port); \
} else { \
IP4ADDR_PORT_TO_SOCKADDR(((struct sockaddr_in*)(sockaddr)), ipXaddr, port); \
} } while(0)
#define SOCKADDR6_TO_IP6ADDR_PORT(sin6, ipXaddr, port) do { \
inet6_addr_to_ip6addr(ipX_2_ip6(ipXaddr), &((sin6)->sin6_addr)); \
(port) = (sin6)->sin6_port; }while(0)
#define SOCKADDR_TO_IPXADDR_PORT(isipv6, sockaddr, ipXaddr, port) do { \
if (isipv6) { \
SOCKADDR6_TO_IP6ADDR_PORT(((struct sockaddr_in6*)(sockaddr)), ipXaddr, port); \
} else { \
SOCKADDR4_TO_IP4ADDR_PORT(((struct sockaddr_in*)(sockaddr)), ipXaddr, port); \
} } while(0)
#define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (((domain) == AF_INET) ? \
(netconn_type) : ((netconn_type) | NETCONN_TYPE_IPV6))
#else /* LWIP_IPV6 */
#define SOCK_ADDR_MATCH(name, sock) (((name)->sa_family) == AF_INET)
#define IS_SOCK_ADDR_LEN_VALID(namelen) ((namelen) == sizeof(struct sockaddr_in))
#define IS_SOCK_ADDR_TYPE_VALID(name) ((name)->sa_family == AF_INET)
#define SOCK_ADDR_TYPE_MATCH(name, sock) 1
#define IPXADDR_PORT_TO_SOCKADDR(isipv6, sockaddr, ipXaddr, port) \
IP4ADDR_PORT_TO_SOCKADDR(((struct sockaddr_in*)sockaddr), ipXaddr, port)
#define SOCKADDR_TO_IPXADDR_PORT(isipv6, sockaddr, ipXaddr, port) \
IP4ADDR_PORT_TO_SOCKADDR(((struct sockaddr_in*)(sockaddr)), ipXaddr, port)
#define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (netconn_type)
#endif /* LWIP_IPV6 */
#define IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) (((name)->sa_family == AF_UNSPEC) || \
IS_SOCK_ADDR_TYPE_VALID(name))
#define SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock) (((name)->sa_family == AF_UNSPEC) || \
SOCK_ADDR_TYPE_MATCH(name, sock))
#define IS_SOCK_ADDR_ALIGNED(name) ((((mem_ptr_t)(name)) % 4) == 0)
#define NUM_SOCKETS MEMP_NUM_NETCONN
@@ -323,19 +373,9 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
{
struct lwip_sock *sock, *nsock;
struct netconn *newconn;
union {
ip_addr_t ip4;
#if LWIP_IPV6
ip6_addr_t ip6;
#endif /* LWIP_IPV6 */
} naddr;
ipX_addr_t naddr;
u16_t port;
int newsock;
struct sockaddr tempaddr;
struct sockaddr_in * sin;
#if LWIP_IPV6
struct sockaddr_in6 * sin6;
#endif /* LWIP_IPV6 */
err_t err;
SYS_ARCH_DECL_PROTECT(lev);
@@ -362,47 +402,25 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
/* Prevent automatic window updates, we do this on our own! */
netconn_set_noautorecved(newconn, 1);
/* get the IP address and port of the remote host */
err = netconn_peer(newconn, &naddr.ip4, &port);
if (err != ERR_OK) {
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err));
netconn_delete(newconn);
sock_set_errno(sock, err_to_errno(err));
return -1;
}
/* Note that POSIX only requires us to check addr is non-NULL. addrlen must
* not be NULL if addr is valid.
*/
if (NULL != addr) {
if (addr != NULL) {
struct sockaddr tempaddr;
/* get the IP address and port of the remote host */
err = netconn_peer(newconn, ipX_2_ip(&naddr), &port);
if (err != ERR_OK) {
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err));
netconn_delete(newconn);
sock_set_errno(sock, err_to_errno(err));
return -1;
}
LWIP_ASSERT("addr valid but addrlen NULL", addrlen != NULL);
memset(&tempaddr, 0, sizeof(tempaddr));
#if LWIP_IPV6
if (NETCONNTYPE_ISIPV6(newconn->type)) {
sin6 = (struct sockaddr_in6 *)&tempaddr;
sin6->sin6_len = sizeof(struct sockaddr_in6);
sin6->sin6_family = AF_INET6;
sin6->sin6_port = htons(port);
sin6->sin6_flowinfo = 0;
inet6_addr_from_ip6addr(&sin6->sin6_addr, &naddr.ip6);
if (*addrlen > sin6->sin6_len)
*addrlen = sin6->sin6_len;
IPXADDR_PORT_TO_SOCKADDR(NETCONNTYPE_ISIPV6(newconn->type), &tempaddr, &naddr, port);
if (*addrlen > tempaddr.sa_len) {
*addrlen = tempaddr.sa_len;
}
else
#endif /* LWIP_IPV6 */
{
sin = (struct sockaddr_in *)&tempaddr;
sin->sin_len = sizeof(struct sockaddr_in);
sin->sin_family = AF_INET;
sin->sin_port = htons(port);
inet_addr_from_ipaddr(&sin->sin_addr, &naddr.ip4);
if (*addrlen > sin->sin_len)
*addrlen = sin->sin_len;
}
MEMCPY(addr, &tempaddr, *addrlen);
}
@@ -426,17 +444,12 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
newconn->socket = newsock;
SYS_ARCH_UNPROTECT(lev);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock));
#if LWIP_IPV6
if (NETCONNTYPE_ISIPV6(newconn->type)) {
ip6_addr_debug_print(SOCKETS_DEBUG, &naddr.ip6);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d", s, newsock));
if (addr != NULL) {
LWIP_DEBUGF(SOCKETS_DEBUG, (" addr="));
ipX_addr_debug_print(NETCONNTYPE_ISIPV6(newconn->type), SOCKETS_DEBUG, &naddr);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port));
}
else
#endif /* LWIP_IPV6 */
{
ip_addr_debug_print(SOCKETS_DEBUG, &naddr.ip4);
}
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port));
sock_set_errno(sock, 0);
return newsock;
@@ -446,53 +459,32 @@ int
lwip_bind(int s, const struct sockaddr *name, socklen_t namelen)
{
struct lwip_sock *sock;
union {
ip_addr_t ip4;
#if LWIP_IPV6
ip6_addr_t ip6;
#endif /* LWIP_IPV6 */
} local_addr;
ipX_addr_t local_addr;
u16_t local_port;
err_t err;
const struct sockaddr_in *name_in;
#if LWIP_IPV6
const struct sockaddr_in6 *name_in6;
#endif /* LWIP_IPV6 */
sock = get_socket(s);
if (!sock) {
return -1;
}
if (SOCK_ADDR_TYPE_MATCH(name, sock)) {
/* sockaddr does not match socket type (IPv4/IPv6) */
sock_set_errno(sock, err_to_errno(ERR_VAL));
return -1;
}
/* check size, familiy and alignment of 'name' */
LWIP_ERROR("lwip_bind: invalid address", ((namelen == sizeof(struct sockaddr_in)) &&
SOCK_ADDR_MATCH(name, sock) &&
((((mem_ptr_t)name) % 4) == 0)),
LWIP_ERROR("lwip_bind: invalid address", (IS_SOCK_ADDR_LEN_VALID(namelen) &&
IS_SOCK_ADDR_TYPE_VALID(name) && IS_SOCK_ADDR_ALIGNED(name)),
sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);
SOCKADDR_TO_IPXADDR_PORT((name->sa_family == AF_INET6), name, &local_addr, local_port);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s));
#if LWIP_IPV6
if ((name->sa_family) == AF_INET6) {
name_in6 = (const struct sockaddr_in6 *)(void*)name;
inet6_addr_to_ip6addr(&local_addr.ip6, &name_in6->sin6_addr);
ip6_addr_debug_print(SOCKETS_DEBUG, &local_addr.ip6);
local_port = name_in6->sin6_port;
}
else
#endif /* LWIP_IPV6 */
{
name_in = (const struct sockaddr_in *)(void*)name;
inet_addr_to_ipaddr(&local_addr.ip4, &name_in->sin_addr);
ip_addr_debug_print(SOCKETS_DEBUG, &local_addr.ip4);
local_port = name_in->sin_port;
}
ipX_addr_debug_print(name->sa_family == AF_INET6, SOCKETS_DEBUG, &local_addr);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(local_port)));
err = netconn_bind(sock->conn, &local_addr.ip4, ntohs(local_port));
err = netconn_bind(sock->conn, ipX_2_ip(&local_addr), ntohs(local_port));
if (err != ERR_OK) {
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err));
@@ -542,48 +534,28 @@ lwip_connect(int s, const struct sockaddr *name, socklen_t namelen)
return -1;
}
if (SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) {
/* sockaddr does not match socket type (IPv4/IPv6) */
sock_set_errno(sock, err_to_errno(ERR_VAL));
return -1;
}
/* check size, familiy and alignment of 'name' */
LWIP_ERROR("lwip_connect: invalid address", ((namelen == sizeof(struct sockaddr_in)) &&
SOCK_ADDR_MATCH(name, sock) &&
((((mem_ptr_t)name) % 4) == 0)),
LWIP_ERROR("lwip_connect: invalid address", IS_SOCK_ADDR_LEN_VALID(namelen) &&
IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) && IS_SOCK_ADDR_ALIGNED(name),
sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);
if (name->sa_family == AF_UNSPEC) {
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s));
err = netconn_disconnect(sock->conn);
}
#if LWIP_IPV6
else if (name->sa_family == AF_INET6) {
const struct sockaddr_in6 *name_in6;
ip6_addr_t remote_addr;
} else {
ipX_addr_t remote_addr;
u16_t remote_port;
name_in6 = (const struct sockaddr_in6 *)(void*)name;
inet6_addr_to_ip6addr(&remote_addr, &name_in6->sin6_addr);
remote_port = name_in6->sin6_port;
SOCKADDR_TO_IPXADDR_PORT((name->sa_family == AF_INET6), name, &remote_addr, remote_port);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s));
ip6_addr_debug_print(SOCKETS_DEBUG, &remote_addr);
ipX_addr_debug_print(name->sa_family == AF_INET6, SOCKETS_DEBUG, &remote_addr);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(remote_port)));
err = netconn_connect(sock->conn, (ip_addr_t *)&remote_addr, ntohs(remote_port));
}
#endif /* LWIP_IPV6 */
else {
const struct sockaddr_in *name_in;
ip_addr_t remote_addr;
u16_t remote_port;
name_in = (const struct sockaddr_in *)(void*)name;
inet_addr_to_ipaddr(&remote_addr, &name_in->sin_addr);
remote_port = name_in->sin_port;
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s));
ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(remote_port)));
err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));
err = netconn_connect(sock->conn, ipX_2_ip(&remote_addr), ntohs(remote_port));
}
if (err != ERR_OK) {
@@ -635,14 +607,13 @@ lwip_listen(int s, int backlog)
int
lwip_recvfrom(int s, void *mem, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen)
struct sockaddr *from, socklen_t *fromlen)
{
struct lwip_sock *sock;
void *buf = NULL;
struct pbuf *p;
u16_t buflen, copylen;
int off = 0;
u16_t port;
u8_t done = 0;
err_t err;
@@ -747,64 +718,23 @@ lwip_recvfrom(int s, void *mem, size_t len, int flags,
if (from && fromlen)
#endif /* !SOCKETS_DEBUG */
{
u16_t port;
ipX_addr_t tmpaddr;
ipX_addr_t *fromaddr;
struct sockaddr saddr;
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));
#if LWIP_IPV6
if (NETCONNTYPE_ISIPV6(netconn_type(sock->conn))) {
ip6_addr_t *fromaddr6;
ip6_addr_t tmpaddr6;
struct sockaddr_in6 sin6;
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
/* @todo: implement netconn_getaddr() for IPv6 addresses */
ip6_addr_set_any(&tmpaddr6);
fromaddr6 = &tmpaddr6;
port = 0;
} else {
fromaddr6 = netbuf_fromaddr_ip6((struct netbuf *)buf);
port = netbuf_fromport((struct netbuf *)buf);
}
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_len = sizeof(sin6);
sin6.sin6_family = AF_INET6;
sin6.sin6_port = htons(port);
inet6_addr_from_ip6addr(&sin6.sin6_addr, fromaddr6);
if (from && fromlen) {
if (*fromlen > sizeof(sin6)) {
*fromlen = sizeof(sin6);
}
MEMCPY(from, &sin6, *fromlen);
}
ip6_addr_debug_print(SOCKETS_DEBUG, fromaddr6);
} else
#endif /* LWIP_IPV6 */
{
ip_addr_t *fromaddr4;
ip_addr_t tmpaddr4;
struct sockaddr_in sin;
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
fromaddr4 = &tmpaddr4;
netconn_getaddr(sock->conn, fromaddr4, &port, 0);
} else {
fromaddr4 = netbuf_fromaddr((struct netbuf *)buf);
port = netbuf_fromport((struct netbuf *)buf);
}
memset(&sin, 0, sizeof(sin));
sin.sin_len = sizeof(sin);
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
inet_addr_from_ipaddr(&sin.sin_addr, fromaddr4);
if (from && fromlen) {
if (*fromlen > sizeof(sin)) {
*fromlen = sizeof(sin);
}
MEMCPY(from, &sin, *fromlen);
}
ip_addr_debug_print(SOCKETS_DEBUG, &fromaddr4);
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
fromaddr = &tmpaddr;
/* @todo: this does not work for IPv6, yet */
netconn_getaddr(sock->conn, ipX_2_ip(fromaddr), &port, 0);
} else {
port = netbuf_fromport((struct netbuf *)buf);
fromaddr = netbuf_fromaddr_ipX((struct netbuf *)buf);
}
IPXADDR_PORT_TO_SOCKADDR(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)),
&saddr, fromaddr, port);
ipX_addr_debug_print(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)),
SOCKETS_DEBUG, fromaddr);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off));
}
}
@@ -866,7 +796,7 @@ lwip_send(int s, const void *data, size_t size, int flags)
return -1;
}
if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_TCP) {
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) {
#if (LWIP_UDP || LWIP_RAW)
return lwip_sendto(s, data, size, flags, NULL, 0);
#else /* (LWIP_UDP || LWIP_RAW) */
@@ -910,7 +840,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
return -1;
}
if (NETCONNTYPE_GROUP(sock->conn->type) == NETCONN_TCP) {
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) {
#if LWIP_TCP
return lwip_send(s, data, size, flags);
#else /* LWIP_TCP */
@@ -920,13 +850,18 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
#endif /* LWIP_TCP */
}
if (SOCK_ADDR_TYPE_MATCH(to, sock)) {
/* sockaddr does not match socket type (IPv4/IPv6) */
sock_set_errno(sock, err_to_errno(ERR_VAL));
return -1;
}
/* @todo: split into multiple sendto's? */
LWIP_ASSERT("lwip_sendto: size must fit in u16_t", size <= 0xffff);
short_size = (u16_t)size;
LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) ||
((tolen == sizeof(struct sockaddr_in)) &&
SOCK_ADDR_MATCH(to, sock) &&
((((mem_ptr_t)to) % 4) == 0))),
(IS_SOCK_ADDR_LEN_VALID(tolen) &&
IS_SOCK_ADDR_TYPE_VALID(to) && IS_SOCK_ADDR_ALIGNED(to))),
sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);
#if LWIP_TCPIP_CORE_LOCKING
@@ -943,7 +878,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
if (p != NULL) {
#if LWIP_CHECKSUM_ON_COPY
u16_t chksum = 0;
if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_RAW) {
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_RAW) {
chksum = LWIP_CHKSUM_COPY(p->payload, data, short_size);
} else
#endif /* LWIP_CHECKSUM_ON_COPY */
@@ -960,7 +895,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
const struct sockaddr_in6 *to_in6;
to_in6 = (const struct sockaddr_in6 *)(void*)to;
inet6_addr_to_ip6addr_p(remote_addr6, &to_in6->sin6_addr);
remote_addr = (ip_addr_t *)remote_addr6;
remote_addr = ip6_2_ip(remote_addr6);
remote_port = ntohs(to_in6->sin6_port);
}
else
@@ -974,19 +909,23 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
} else {
remote_addr = IP_ADDR_ANY;
#if LWIP_IPV6
if (NETCONNTYPE_ISIPV6(sock->conn->type)) {
remote_addr6 = IP6_ADDR_ANY;
remote_addr = (ip_addr_t *)remote_addr6;
if (NETCONNTYPE_ISIPV6(netconn_type(sock->conn))) {
remote_addr = ip6_2_ip(IP6_ADDR_ANY);
}
else
#endif /* LWIP_IPV6 */
{
remote_addr = IP_ADDR_ANY;
}
if (NETCONNTYPE_GROUP(sock->conn->type) == NETCONN_RAW) {
remote_port = 0;
} else {
remote_port = sock->conn->pcb.udp->remote_port;
}
}
LOCK_TCPIP_CORE();
if (NETCONNTYPE_GROUP(sock->conn->type) == NETCONN_RAW) {
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_RAW) {
err = sock->conn->last_err = raw_sendto(sock->conn->pcb.raw, p, remote_addr);
} else {
#if LWIP_UDP
@@ -1015,48 +954,18 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
buf.flags = 0;
#endif /* LWIP_CHECKSUM_ON_COPY */
if (to) {
#if LWIP_IPV6
if ((to->sa_family) == AF_INET6) {
const struct sockaddr_in6 *to_in6;
to_in6 = (const struct sockaddr_in6 *)(void*)to;
inet6_addr_to_ip6addr(&buf.addr.ip6, &to_in6->sin6_addr);
remote_port = ntohs(to_in6->sin6_port);
}
else
#endif /* LWIP_IPV6 */
{
const struct sockaddr_in *to_in;
to_in = (const struct sockaddr_in *)(void*)to;
inet_addr_to_ipaddr(&buf.addr.ip4, &to_in->sin_addr);
remote_port = ntohs(to_in->sin_port);
}
netbuf_fromport(&buf) = remote_port;
SOCKADDR_TO_IPXADDR_PORT((to->sa_family) == AF_INET6, to, &buf.addr, remote_port);
} else {
remote_port = 0;
#if LWIP_IPV6
if (NETCONNTYPE_ISIPV6(sock->conn->type)) {
ip6_addr_set_any(&buf.addr.ip6);
}
else
#endif /* LWIP_IPV6 */
{
ip_addr_set_any(&buf.addr.ip4);
}
netbuf_fromport(&buf) = 0;
ipX_addr_set_any(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), &buf.addr);
}
netbuf_fromport(&buf) = remote_port;
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=",
s, data, short_size, flags));
#if LWIP_IPV6
if (NETCONNTYPE_ISIPV6(sock->conn->type)) {
ip6_addr_debug_print(SOCKETS_DEBUG, &buf.addr.ip6);
}
else
#endif /* LWIP_IPV6 */
{
ip_addr_debug_print(SOCKETS_DEBUG, &buf.addr.ip4);
}
ipX_addr_debug_print(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)),
SOCKETS_DEBUG, &buf.addr);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port));
/* make the buffer point to the data that should be sent */
@@ -1066,7 +975,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
err = ERR_MEM;
} else {
#if LWIP_CHECKSUM_ON_COPY
if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_RAW) {
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_RAW) {
u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size);
netbuf_set_chksum(&buf, chksum);
err = ERR_OK;
@@ -1098,40 +1007,26 @@ lwip_socket(int domain, int type, int protocol)
int i;
#if !LWIP_IPV6
LWIP_UNUSED_ARG(domain);
LWIP_UNUSED_ARG(domain); /* @todo: check this */
#endif /* LWIP_IPV6 */
/* create a netconn */
switch (type) {
case SOCK_RAW:
#if LWIP_IPV6
conn = netconn_new_with_proto_and_callback((domain == AF_INET) ? NETCONN_RAW : NETCONN_RAW_IPV6,
conn = netconn_new_with_proto_and_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_RAW),
(u8_t)protocol, event_callback);
#else /* LWIP_IPV6 */
conn = netconn_new_with_proto_and_callback(NETCONN_RAW, (u8_t)protocol, event_callback);
#endif /* LWIP_IPV6 */
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ",
domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
break;
case SOCK_DGRAM:
#if LWIP_IPV6
conn = netconn_new_with_callback((domain == AF_INET) ?
((protocol == IPPROTO_UDPLITE) ? NETCONN_UDPLITE : NETCONN_UDP) :
((protocol == IPPROTO_UDPLITE) ? NETCONN_UDPLITE_IPV6 : NETCONN_UDP_IPV6) ,
conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain,
((protocol == IPPROTO_UDPLITE) ? NETCONN_UDPLITE : NETCONN_UDP)) ,
event_callback);
#else /* LWIP_IPV6 */
conn = netconn_new_with_callback( (protocol == IPPROTO_UDPLITE) ?
NETCONN_UDPLITE : NETCONN_UDP, event_callback);
#endif /* LWIP_IPV6 */
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ",
domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
break;
case SOCK_STREAM:
#if LWIP_IPV6
conn = netconn_new_with_callback((domain == AF_INET) ? NETCONN_TCP : NETCONN_TCP_IPV6, event_callback);
#else /* LWIP_IPV6 */
conn = netconn_new_with_callback(NETCONN_TCP, event_callback);
#endif /* LWIP_IPV6 */
conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_TCP), event_callback);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ",
domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol));
if (conn != NULL) {
@@ -1399,8 +1294,6 @@ return_copy_fdsets:
if (exceptset) {
*exceptset = lexceptset;
}
return nready;
}
@@ -1573,63 +1466,31 @@ static int
lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local)
{
struct lwip_sock *sock;
struct sockaddr saddr;
ipX_addr_t naddr;
u16_t port;
sock = get_socket(s);
if (!sock) {
return -1;
}
#if LWIP_IPV6
if (NETCONNTYPE_ISIPV6(sock->conn->type)) {
struct sockaddr_in6 sin6;
ip6_addr_t naddr6;
/* get the IP address and port */
/* @todo: this does not work for IPv6, yet */
netconn_getaddr(sock->conn, ipX_2_ip(&naddr), &port, local);
IPXADDR_PORT_TO_SOCKADDR(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)),
&saddr, &naddr, port);
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_len = sizeof(sin6);
sin6.sin6_family = AF_INET6;
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s));
ipX_addr_debug_print(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)),
SOCKETS_DEBUG, &naddr);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", port));
/* get the IP address and port */
netconn_getaddr(sock->conn, (ip_addr_t *)&naddr6, &sin6.sin6_port, local);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s));
ip6_addr_debug_print(SOCKETS_DEBUG, &naddr6);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", sin6.sin6_port));
sin6.sin6_port = htons(sin6.sin6_port);
inet6_addr_from_ip6addr(&sin6.sin6_addr, &naddr6);
if (*namelen > sizeof(sin6)) {
*namelen = sizeof(sin6);
}
MEMCPY(name, &sin6, *namelen);
if (*namelen > saddr.sa_len) {
*namelen = saddr.sa_len;
}
else
#endif /* LWIP_IPV6 */
{
struct sockaddr_in sin;
ip_addr_t naddr;
MEMCPY(name, &saddr, *namelen);
memset(&sin, 0, sizeof(sin));
sin.sin_len = sizeof(sin);
sin.sin_family = AF_INET;
/* get the IP address and port */
netconn_getaddr(sock->conn, &naddr, &sin.sin_port, local);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s));
ip_addr_debug_print(SOCKETS_DEBUG, &naddr);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", sin.sin_port));
sin.sin_port = htons(sin.sin_port);
inet_addr_from_ipaddr(&sin.sin_addr, &naddr);
if (*namelen > sizeof(sin)) {
*namelen = sizeof(sin);
}
MEMCPY(name, &sin, *namelen);
}
sock_set_errno(sock, 0);
return 0;
}
@@ -1703,12 +1564,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
err = EINVAL;
}
#if LWIP_UDP
if (
#if LWIP_IPV6
((sock->conn->type != NETCONN_UDP) && (sock->conn->type != NETCONN_UDP_IPV6)) ||
#else /* LWIP_IPV6 */
(sock->conn->type != NETCONN_UDP) ||
#endif /* LWIP_IPV6 */
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP ||
((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) {
/* this flag is only available for UDP, not for UDP lite */
err = EAFNOSUPPORT;
@@ -1750,7 +1606,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
if (*optlen < sizeof(u8_t)) {
err = EINVAL;
}
if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) {
err = EAFNOSUPPORT;
}
break;
@@ -1772,7 +1628,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
}
/* If this is no TCP socket, ignore any options. */
if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_TCP)
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP)
return 0;
switch (optname) {
@@ -1801,11 +1657,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
}
/* If this is no UDP lite socket, ignore any options. */
#if LWIP_IPV6
if ((sock->conn->type != NETCONN_UDPLITE) && (sock->conn->type != NETCONN_UDPLITE_IPV6)) {
#else /* LWIP_IPV6 */
if (sock->conn->type != NETCONN_UDPLITE) {
#endif /* LWIP_IPV6 */
if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) {
return 0;
}
@@ -1899,7 +1751,7 @@ lwip_getsockopt_internal(void *arg)
break;
case SO_TYPE:
switch (NETCONNTYPE_GROUP(sock->conn->type)) {
switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) {
case NETCONN_RAW:
*(int*)optval = SOCK_RAW;
break;
@@ -1910,11 +1762,11 @@ lwip_getsockopt_internal(void *arg)
*(int*)optval = SOCK_DGRAM;
break;
default: /* unrecognized socket type */
*(int*)optval = sock->conn->type;
*(int*)optval = netconn_type(sock->conn);
LWIP_DEBUGF(SOCKETS_DEBUG,
("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n",
s, *(int *)optval));
} /* switch (sock->conn->type) */
} /* switch (netconn_type(sock->conn)) */
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n",
s, *(int *)optval));
break;
@@ -2109,12 +1961,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
err = EINVAL;
}
#if LWIP_UDP
if (
#if LWIP_IPV6
((sock->conn->type != NETCONN_UDP) && (sock->conn->type != NETCONN_UDP_IPV6)) ||
#else /* LWIP_IPV6 */
(sock->conn->type != NETCONN_UDP) ||
#endif /* LWIP_IPV6 */
if (NETCONNTYPE_GROUP((netconn_type(sock->conn) != NETCONN_UDP)) ||
((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) {
/* this flag is only available for UDP, not for UDP lite */
err = EAFNOSUPPORT;
@@ -2145,7 +1992,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
if (optlen < sizeof(u8_t)) {
err = EINVAL;
}
if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) {
err = EAFNOSUPPORT;
}
break;
@@ -2153,7 +2000,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
if (optlen < sizeof(struct in_addr)) {
err = EINVAL;
}
if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) {
err = EAFNOSUPPORT;
}
break;
@@ -2161,7 +2008,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
if (optlen < sizeof(u8_t)) {
err = EINVAL;
}
if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) {
err = EAFNOSUPPORT;
}
break;
@@ -2170,7 +2017,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
if (optlen < sizeof(struct ip_mreq)) {
err = EINVAL;
}
if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) {
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) {
err = EAFNOSUPPORT;
}
break;
@@ -2191,7 +2038,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
}
/* If this is no TCP socket, ignore any options. */
if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_TCP)
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP)
return 0;
switch (optname) {
@@ -2220,11 +2067,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
}
/* If this is no UDP lite socket, ignore any options. */
#if LWIP_IPV6
if ((sock->conn->type != NETCONN_UDPLITE) && (sock->conn->type != NETCONN_UDPLITE_IPV6))
#else /* LWIP_IPV6 */
if (sock->conn->type != NETCONN_UDPLITE)
#endif /* LWIP_IPV6 */
if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn)))
return 0;
switch (optname) {