mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
posix: redo socket API to use conn
This commit is contained in:
parent
fda6155071
commit
624530c7d0
11
Makefile.dep
11
Makefile.dep
@ -1,9 +1,5 @@
|
||||
ifneq (,$(filter libcoap,$(USEPKG)))
|
||||
USEMODULE += pnet
|
||||
endif
|
||||
|
||||
ifneq (,$(filter pnet,$(USEMODULE)))
|
||||
USEMODULE += vtimer
|
||||
USEMODULE += posix_sockets
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_%,$(filter-out gnrc_netapi gnrc_netreg gnrc_netif% gnrc_pktbuf,$(USEMODULE))))
|
||||
@ -276,6 +272,11 @@ ifneq (,$(filter newlib,$(USEMODULE)))
|
||||
USEMODULE += uart_stdio
|
||||
endif
|
||||
|
||||
ifneq (,$(filter posix_sockets,$(USEMODULE)))
|
||||
USEMODULE += posix
|
||||
USEMODULE += random
|
||||
endif
|
||||
|
||||
ifneq (,$(filter posix,$(USEMODULE)))
|
||||
USEMODULE += timex
|
||||
USEMODULE += vtimer
|
||||
|
@ -1,5 +1,5 @@
|
||||
ifneq (,$(filter pnet,$(USEMODULE)))
|
||||
DIRS += posix/pnet
|
||||
ifneq (,$(filter posix_sockets,$(USEMODULE)))
|
||||
DIRS += posix/sockets
|
||||
endif
|
||||
ifneq (,$(filter pthread,$(USEMODULE)))
|
||||
DIRS += posix/pthread
|
||||
|
@ -18,7 +18,7 @@ ifneq (,$(filter posix,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/sys/posix/include
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/sys/net/include
|
||||
endif
|
||||
ifneq (,$(filter pnet,$(USEMODULE)))
|
||||
ifneq (,$(filter posix_sockets,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/sys/posix/include
|
||||
endif
|
||||
ifneq (,$(filter pthread,$(USEMODULE)))
|
||||
|
@ -31,29 +31,13 @@
|
||||
#include "net/af.h"
|
||||
#include "net/ipv4/addr.h"
|
||||
#include "net/ipv6/addr.h"
|
||||
#include "socket_base/socket.h"
|
||||
#include "sys/bytes.h"
|
||||
#include "netinet/in.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef uint16_t in_port_t; /**< Internet port type */
|
||||
typedef uint32_t in_addr_t; /**< IPv4 address type */
|
||||
|
||||
/**
|
||||
* @brief Alias to @ref IPV4_ADDR_MAX_STR_LEN
|
||||
*/
|
||||
#ifndef INET_ADDRSTRLEN
|
||||
#define INET_ADDRSTRLEN (IPV4_ADDR_MAX_STR_LEN)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Alias to @ref IPV6_ADDR_MAX_STR_LEN
|
||||
*/
|
||||
#ifndef INET6_ADDRSTRLEN
|
||||
#define INET6_ADDRSTRLEN (IPV6_ADDR_MAX_STR_LEN)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Size in byte of an IPv4 address
|
||||
*/
|
||||
@ -68,66 +52,6 @@ typedef uint32_t in_addr_t; /**< IPv4 address type */
|
||||
#define IN6ADDRSZ (sizeof(ipv6_addr_t))
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief IPv4 address structure type.
|
||||
*/
|
||||
struct in_addr {
|
||||
in_addr_t s_addr; ///< an IPv4 address
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Convert values between host and network byte order.
|
||||
*
|
||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/htonl.html">
|
||||
* The Open Group Base Specification Issue 7, htonl
|
||||
* </a>
|
||||
*
|
||||
* @param[in] hostlong A 32 bit number.
|
||||
* @return The argument value converted from host to network byte
|
||||
* order.
|
||||
*/
|
||||
#define htonl(hostlong) HTONL(hostlong)
|
||||
|
||||
/**
|
||||
* @brief Convert values between host and network byte order.
|
||||
*
|
||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/htons.html">
|
||||
* The Open Group Base Specification Issue 7, htons
|
||||
* </a>
|
||||
*
|
||||
* @param[in] hostshort A 16 bit number.
|
||||
* @return The argument value converted from host to network byte
|
||||
* order.
|
||||
*/
|
||||
#define htons(hostshort) HTONS(hostshort)
|
||||
|
||||
/**
|
||||
* @brief Convert values between host and network byte order.
|
||||
*
|
||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/ntohl.html">
|
||||
* The Open Group Base Specification Issue 7, ntohl
|
||||
* </a>
|
||||
*
|
||||
* @param[in] netlong A 32-bit integer number.
|
||||
* @return The argument value converted from network to host byte
|
||||
* order.
|
||||
*/
|
||||
#define ntohl(netlong) NTOHL(netlong)
|
||||
|
||||
/**
|
||||
* @brief Convert values between host and network byte order.
|
||||
*
|
||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/ntohs.html">
|
||||
* The Open Group Base Specification Issue 7, ntohs
|
||||
* </a>
|
||||
*
|
||||
* @param[in] netshort A 16-bit integer number.
|
||||
* @return The argument value converted from network to host byte
|
||||
* order.
|
||||
*/
|
||||
#define ntohs(netshort) NTOHS(netshort)
|
||||
|
||||
/**
|
||||
* @brief Converts an IP address to its string representation
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Freie Universität Berlin
|
||||
* Copyright (C) 2013-15 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
|
||||
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup pnet
|
||||
* @addtogroup posix_sockets
|
||||
* @{
|
||||
*/
|
||||
|
||||
@ -25,105 +25,17 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "net/gnrc/ipv6.h"
|
||||
#include "socket_base/socket.h"
|
||||
|
||||
#include "net/protnum.h"
|
||||
#include "net/ipv6/addr.h"
|
||||
#include "sys/bytes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* IPv4 socket address type.
|
||||
*/
|
||||
struct sockaddr_in {
|
||||
sa_family_t sin_family; ///< Protocol family, always AF_INET.
|
||||
in_port_t sin_port; ///< Port number
|
||||
struct in_addr sin_addr; ///< IPv4 address
|
||||
};
|
||||
|
||||
/**
|
||||
* IPv6 address structure type.
|
||||
*/
|
||||
struct in6_addr {
|
||||
/**
|
||||
* Private RIOT-internal data, needs not to be touched by the user.
|
||||
*/
|
||||
ipv6_addr_t __in6_u;
|
||||
|
||||
/**
|
||||
* IPv6 Address represented as sequence of 8-bit numbers. Member of
|
||||
* struct in6_addr.
|
||||
*/
|
||||
#define s6_addr __in6_u.uint8
|
||||
|
||||
/**
|
||||
* IPv6 Address represented as sequence of 16-bit numbers. Member of
|
||||
* struct in6_addr.
|
||||
*/
|
||||
#define s6_addr16 __in6_u.uint16
|
||||
|
||||
/**
|
||||
* IPv6 Address represented as sequence of 32-bit numbers. Member of
|
||||
* struct in6_addr.
|
||||
*/
|
||||
#define s6_addr32 __in6_u.uint32
|
||||
};
|
||||
|
||||
/**
|
||||
* IPv6 socket address type.
|
||||
*/
|
||||
struct sockaddr_in6 {
|
||||
/**
|
||||
* Private RIOT-internal data, needs not to be touched by the user.
|
||||
*/
|
||||
sockaddr6_t __in6_a;
|
||||
|
||||
/**
|
||||
* Protocol family, always AF_INET6. Member of struct sockaddr_in6
|
||||
*/
|
||||
#define sin6_family __in6_a.sin6_family
|
||||
|
||||
/**
|
||||
* Port number. Member of struct sockaddr_in6
|
||||
*/
|
||||
#define sin6_port __in6_a.sin6_port
|
||||
|
||||
/**
|
||||
* IPv6 traffic class and flow information. Member of struct sockaddr_in6
|
||||
*/
|
||||
#define sin6_flowinfo __in6_a.sin6_flowinfo
|
||||
|
||||
/**
|
||||
* IPv6 address. Member of struct sockaddr_in6
|
||||
*/
|
||||
#define sin6_addr __in6_a.sin6_addr
|
||||
|
||||
/**
|
||||
* Set of interfaces for a scope.
|
||||
*/
|
||||
uint32_t sin6_scope_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* IPv6 wildcard address.
|
||||
*/
|
||||
#define IN6ADDR_ANY_INIT {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
|
||||
|
||||
/**
|
||||
* IPv6 loopback address.
|
||||
*/
|
||||
#define IN6ADDR_LOOPBACK_INIT {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}
|
||||
|
||||
/**
|
||||
* IPv6 socket address for the wildcard address.
|
||||
*/
|
||||
extern const struct sockaddr_in6 in6addr_any;
|
||||
|
||||
/**
|
||||
* IPv6 socket address for the loopback address.
|
||||
*/
|
||||
extern const struct sockaddr_in6 in6addr_loopback;
|
||||
#define INET_ADDRSTRLEN (16) /**< Length of the string form for IPv4. */
|
||||
#define INET6_ADDRSTRLEN (46) /**< Length of the string form for IPv6. */
|
||||
|
||||
/**
|
||||
* IPv4 local host address.
|
||||
@ -136,24 +48,221 @@ extern const struct sockaddr_in6 in6addr_loopback;
|
||||
#define INADDR_BROADCAST ((in_addr_t)0xffffffff)
|
||||
|
||||
/**
|
||||
* Multicast hop limit option name for getsockopt() or setsockopt()
|
||||
*
|
||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html">
|
||||
* The Open Group Base Specification Issue 7, getsockopt
|
||||
* </a>
|
||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html">
|
||||
* The Open Group Base Specification Issue 7, setsockopt
|
||||
* </a>
|
||||
* IPv6 wildcard address.
|
||||
*/
|
||||
#define IPV6_MULTICAST_HOPS 0x12
|
||||
#define IN6ADDR_ANY_INIT IPV6_ADDR_UNSPECIFIED
|
||||
|
||||
/**
|
||||
* Test for IPv6 multicast address.
|
||||
*
|
||||
* @param[in] a An IPv6 address.
|
||||
* @return 1 if *a* is an multicast address, 0 if not.
|
||||
* IPv6 loopback address.
|
||||
*/
|
||||
#define IN6_IS_ADDR_MULTICAST(a) (((const uint8_t *) (a))[0] == 0xff)
|
||||
#define IN6ADDR_LOOPBACK_INIT IPV6_ADDR_LOOPBACK
|
||||
|
||||
/**
|
||||
* @name IPv6 address macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Check if address is the unspecified address (`::`).
|
||||
*
|
||||
* @param[in] addr address of type `const struct in6_addr *`
|
||||
*
|
||||
* @return 0, when an address is not the unspecified address.
|
||||
* @return any other value otherwise.
|
||||
*/
|
||||
#define IN6_IS_ADDR_UNSPECIFIED(addr) ((int)(ipv6_addr_is_unspecified((const ipv6_addr_t *)(addr))))
|
||||
|
||||
/**
|
||||
* @brief Check if address is the loopback address (`::1`).
|
||||
*
|
||||
* @param[in] addr address of type `const struct in6_addr *`
|
||||
*
|
||||
* @return 0, when an address is not the loopback address.
|
||||
* @return any other value otherwise.
|
||||
*/
|
||||
#define IN6_IS_ADDR_LOOPBACK(addr) ((int)(ipv6_addr_is_loopback((const ipv6_addr_t *)(addr))))
|
||||
|
||||
/**
|
||||
* @brief Check if address is a multicast address.
|
||||
*
|
||||
* @param[in] addr address of type `const struct in6_addr *`
|
||||
*
|
||||
* @return 0, when an address is not a multicast address.
|
||||
* @return any other value otherwise.
|
||||
*/
|
||||
#define IN6_IS_ADDR_MULTICAST(addr) ((int)(ipv6_addr_is_multicast((const ipv6_addr_t *)(addr))))
|
||||
|
||||
/**
|
||||
* @brief Check if address is a link-local address.
|
||||
*
|
||||
* @param[in] addr address of type `const struct in6_addr *`
|
||||
*
|
||||
* @return 0, when an address is not a link-local address.
|
||||
* @return any other value otherwise.
|
||||
*/
|
||||
#define IN6_IS_ADDR_LINKLOCAL(addr) ((int)(ipv6_addr_is_link_local((const ipv6_addr_t *)addr)))
|
||||
|
||||
/**
|
||||
* @brief Check if address is a site-local address.
|
||||
*
|
||||
* @param[in] addr address of type `const struct in6_addr *`
|
||||
*
|
||||
* @return 0, when an address is not a site-local address.
|
||||
* @return any other value otherwise.
|
||||
*/
|
||||
#define IN6_IS_ADDR_SITELOCAL(addr) ((int)(ipv6_addr_is_site_local((const ipv6_addr_t *)addr)))
|
||||
|
||||
/**
|
||||
* @brief Check if address is an IPv4 mapped address.
|
||||
*
|
||||
* @param[in] addr address of type `const struct in6_addr *`
|
||||
*
|
||||
* @return 0, when an address is not an IPv4 mapped address.
|
||||
* @return any other value otherwise.
|
||||
*/
|
||||
#define IN6_IS_ADDR_V4MAPPED(addr) ((int)(ipv6_addr_is_ipv4_mapped((const ipv6_addr_t *)addr)))
|
||||
|
||||
/**
|
||||
* @brief Check if address is an IPv4-compatible address.
|
||||
*
|
||||
* @param[in] addr address of type `const struct in6_addr *`
|
||||
*
|
||||
* @return 0, when an address is not an IPv4-compatible address.
|
||||
* @return any other value otherwise.
|
||||
*/
|
||||
#define IN6_IS_ADDR_V4COMPAT(addr) ((int)(ipv6_addr_is_ipv4_compat((const ipv6_addr_t *)addr)))
|
||||
|
||||
/**
|
||||
* @brief Check if address is a multicast node-local address.
|
||||
*
|
||||
* @param[in] addr address of type `const struct in6_addr *`
|
||||
*
|
||||
* @return 0, when an address is not a multicast node-local address.
|
||||
* @return any other value otherwise.
|
||||
*/
|
||||
#define IN6_IS_ADDR_MC_NODELOCAL(addr) (IN6_IS_ADDR_MULTICAST(addr) && \
|
||||
(int)((addr->s6_addr[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_IF_LOCAL))
|
||||
|
||||
/**
|
||||
* @brief Check if address is a multicast link-local address.
|
||||
*
|
||||
* @param[in] addr address of type `const struct in6_addr *`
|
||||
*
|
||||
* @return 0, when an address is not a multicast link-local address.
|
||||
* @return any other value otherwise.
|
||||
*/
|
||||
#define IN6_IS_ADDR_MC_LINKLOCAL(addr) (IN6_IS_ADDR_MULTICAST(addr) && \
|
||||
(int)((addr->s6_addr[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_LINK_LOCAL))
|
||||
|
||||
/**
|
||||
* @brief Check if address is a multicast site-local address.
|
||||
*
|
||||
* @param[in] addr address of type `const struct in6_addr *`
|
||||
*
|
||||
* @return 0, when an address is not a multicast site-local address.
|
||||
* @return any other value otherwise.
|
||||
*/
|
||||
#define IN6_IS_ADDR_MC_SITELOCAL(addr) (IN6_IS_ADDR_MULTICAST(addr) && \
|
||||
(int)((addr->s6_addr[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_SITE_LOCAL))
|
||||
|
||||
/**
|
||||
* @brief Check if address is a multicast organization-local address.
|
||||
*
|
||||
* @param[in] addr address of type `const struct in6_addr *`
|
||||
*
|
||||
* @return 0, when an address is not a multicast organization-local address.
|
||||
* @return any other value otherwise.
|
||||
*/
|
||||
#define IN6_IS_ADDR_MC_ORGLOCAL(addr) (IN6_IS_ADDR_MULTICAST(addr) && \
|
||||
(int)((addr->s6_addr[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_ORG_LOCAL))
|
||||
|
||||
/**
|
||||
* @brief Check if address is a multicast global address.
|
||||
*
|
||||
* @param[in] addr address of type `const struct in6_addr *`
|
||||
*
|
||||
* @return 0, when an address is not a multicast global address.
|
||||
* @return any other value otherwise.
|
||||
*/
|
||||
#define IN6_IS_ADDR_MC_GLOBAL(addr) (IN6_IS_ADDR_MULTICAST(addr) && \
|
||||
(int)((addr->s6_addr[1] & 0x0f) == IPV6_ADDR_MCAST_SCP_GLOBAL))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Protocol numbers for option
|
||||
* @{
|
||||
*/
|
||||
#define IPPROTO_IP (PROTNUM_IPV4) /**< Internet Protocol version 4 */
|
||||
#define IPPROTO_IPV6 (PROTNUM_IPV6) /**< Internet Protocol version 6 */
|
||||
#define IPPROTO_ICMP (PROTNUM_ICMP) /**< Internet Control Message Protocol */
|
||||
#define IPPROTO_ICMPV6 (PROTNUM_ICMPV6) /**< ICMP for IPv6 */
|
||||
#define IPPROTO_RAW (PROTNUM_RESERVED) /**< Raw IP packets protocol */
|
||||
#define IPPROTO_TCP (PROTNUM_TCP) /**< Transmission control protocol */
|
||||
#define IPPROTO_UDP (PROTNUM_UDP) /**< User datagram protocol */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @todo IPv6 option names
|
||||
*/
|
||||
|
||||
typedef uint16_t in_port_t; /**< Internet port type */
|
||||
typedef uint32_t in_addr_t; /**< IPv4 address type */
|
||||
|
||||
/**
|
||||
* IPv4 address structure type.
|
||||
*/
|
||||
struct in_addr {
|
||||
in_addr_t s_addr; /**< an IPv4 address */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief IPv6 address structure type.
|
||||
*/
|
||||
struct in6_addr {
|
||||
uint8_t s6_addr[16]; /**< unsigned 8-bit integer array */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief IPv4 socket address type.
|
||||
* @extends struct sockaddr
|
||||
*/
|
||||
struct sockaddr_in {
|
||||
sa_family_t sin_family; /**< Protocol family, always AF_INET */
|
||||
in_port_t sin_port; /**< Port number */
|
||||
struct in_addr sin_addr; /**< IPv4 address */
|
||||
};
|
||||
|
||||
/**
|
||||
* IPv6 socket address type.
|
||||
* @extends struct sockaddr
|
||||
*/
|
||||
struct sockaddr_in6 {
|
||||
/**
|
||||
* Protocol family, always AF_INET6. Member of struct sockaddr_in6
|
||||
*/
|
||||
int sin6_family; /**< Protocol family, always AF_INET6 */
|
||||
in_port_t sin6_port; /**< Port number */
|
||||
uint32_t sin6_flowinfo; /**< IPv6 traffic class and flow information */
|
||||
struct in6_addr sin6_addr; /**< IPv6 address */
|
||||
uint32_t sin6_scope_id; /**< Set of interfaces for a scope */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief IPv6 multicast request.
|
||||
*/
|
||||
struct ipv6_mreq {
|
||||
struct in6_addr ipv6mr_multiaddr; /**< an IPv6 multicast address */
|
||||
unsigned ipv6mr_interface; /**< interface index, leave 0 for default */
|
||||
};
|
||||
|
||||
/**
|
||||
* IPv6 socket address for the wildcard address.
|
||||
*/
|
||||
extern const struct sockaddr_in6 in6addr_any;
|
||||
|
||||
/**
|
||||
* IPv6 socket address for the loopback address.
|
||||
*/
|
||||
extern const struct sockaddr_in6 in6addr_loopback;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
96
sys/posix/include/sys/bytes.h
Normal file
96
sys/posix/include/sys/bytes.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup posix_sockets
|
||||
*/
|
||||
/**
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief System-internal byte operations.
|
||||
*
|
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
*/
|
||||
#ifndef BYTES_H_
|
||||
#define BYTES_H_
|
||||
|
||||
#include "byteorder.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Convert values between host and network byte order.
|
||||
*
|
||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/htonl.html">
|
||||
* The Open Group Base Specification Issue 7, htonl
|
||||
* </a>
|
||||
*
|
||||
* @param[in] hostlong A 32 bit number.
|
||||
* @return The argument value converted from host to network byte
|
||||
* order.
|
||||
*/
|
||||
#ifndef htonl
|
||||
#define htonl(hostlong) HTONL(hostlong)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Convert values between host and network byte order.
|
||||
*
|
||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/htons.html">
|
||||
* The Open Group Base Specification Issue 7, htons
|
||||
* </a>
|
||||
*
|
||||
* @param[in] hostshort A 16 bit number.
|
||||
* @return The argument value converted from host to network byte
|
||||
* order.
|
||||
*/
|
||||
#ifndef htons
|
||||
#define htons(hostshort) HTONS(hostshort)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Convert values between host and network byte order.
|
||||
*
|
||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/ntohl.html">
|
||||
* The Open Group Base Specification Issue 7, ntohl
|
||||
* </a>
|
||||
*
|
||||
* @param[in] netlong A 32-bit integer number.
|
||||
* @return The argument value converted from network to host byte
|
||||
* order.
|
||||
*/
|
||||
#ifndef ntohl
|
||||
#define ntohl(netlong) NTOHL(netlong)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Convert values between host and network byte order.
|
||||
*
|
||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/ntohs.html">
|
||||
* The Open Group Base Specification Issue 7, ntohs
|
||||
* </a>
|
||||
*
|
||||
* @param[in] netshort A 16-bit integer number.
|
||||
* @return The argument value converted from network to host byte
|
||||
* order.
|
||||
*/
|
||||
#ifndef ntohs
|
||||
#define ntohs(netshort) NTOHS(netshort)
|
||||
#endif
|
||||
|
||||
typedef size_t socklen_t; /**< socket address length */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BYTES_H_ */
|
||||
/** @} */
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Freie Universität Berlin
|
||||
* Copyright (C) 2013-15 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
|
||||
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup pnet
|
||||
* @addtogroup posix_sockets
|
||||
* @{
|
||||
*/
|
||||
|
||||
@ -18,6 +18,12 @@
|
||||
* The Open Group Base Specifications Issue 7, <sys/socket.h>
|
||||
* </a>
|
||||
*
|
||||
* @todo Omitted from original specification for now:
|
||||
* * struct msghdr, struct cmesghdr, and struct linger and all related defines
|
||||
* * getsockopt()/setsockopt() and all related defines.
|
||||
* * shutdown() and all related defines.
|
||||
* * sockatmark()
|
||||
*
|
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
*/
|
||||
#ifndef _SYS_SOCKET_H
|
||||
@ -32,135 +38,81 @@
|
||||
#define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int))
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "kernel_types.h"
|
||||
#include "net/af.h"
|
||||
|
||||
#include "socket_base/socket.h"
|
||||
#include "sys/bytes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum data length for a socket address.
|
||||
*
|
||||
* It is assumed that struct sockaddr_in6 is currently the longest socket address struct.
|
||||
* As such it's data length is taken consisting of the IPv6 address (16 byte), the port (2 byte),
|
||||
* the flow information (4 byte) and the scope ID (4 byte)
|
||||
*/
|
||||
#define SOCKADDR_MAX_DATA_LEN (26)
|
||||
|
||||
/**
|
||||
* @name Socket types
|
||||
* @{
|
||||
*/
|
||||
#define SOCK_DGRAM (1) /**< Datagram socket */
|
||||
#define SOCK_RAW (2) /**< Raw socket */
|
||||
#define SOCK_SEQPACKET (3) /**< Sequenced-packet socket */
|
||||
#define SOCK_STREAM (4) /**< Stream socket */
|
||||
/** @} */
|
||||
|
||||
#define SOL_SOCKET (-1) /**< Options to be accessed at socket level, not protocol level */
|
||||
|
||||
/**
|
||||
* @name Option names
|
||||
* @brief Option names for getsockopt() and setsockopt()
|
||||
* @{
|
||||
*/
|
||||
#define SO_ACCEPTCONN (0) /**< Socket is accepting connections. */
|
||||
#define SO_BROADCAST (1) /**< Transmission of broadcast messages is supported. */
|
||||
#define SO_DEBUG (2) /**< Debugging information is being recorded. */
|
||||
#define SO_DONTROUTE (3) /**< Bypass normal routing. */
|
||||
#define SO_ERROR (4) /**< Socket error status. */
|
||||
#define SO_KEEPALIVE (5) /**< Connections are kept alive with periodic messages. */
|
||||
#define SO_LINGER (6) /**< Socket lingers on close. */
|
||||
#define SO_OOBINLINE (7) /**< Out-of-band data is transmitted in line. */
|
||||
#define SO_RCVBUF (8) /**< Receive buffer size. */
|
||||
#define SO_RCVLOWAT (9) /**< Receive "low water mark". */
|
||||
#define SO_RCVTIMEO (10) /**< Receive timeout. */
|
||||
#define SO_REUSEADDR (11) /**< Reuse of local addresses is supported. */
|
||||
#define SO_SNDBUF (12) /**< Send buffer size. */
|
||||
#define SO_SNDLOWAT (13) /**< Send "low water mark". */
|
||||
#define SO_SNDTIMEO (14) /**< Send timeout. */
|
||||
#define SO_TYPE (15) /**< Socket type. */
|
||||
/** @} */
|
||||
|
||||
typedef unsigned int sa_family_t; /**< address family type */
|
||||
|
||||
/**
|
||||
* @brief Used to define the socket address.
|
||||
*/
|
||||
struct __attribute__((packed)) sockaddr {
|
||||
sa_family_t sa_family; ///< Address family
|
||||
char sa_data[14]; ///< Socket address (variable length data)
|
||||
struct sockaddr {
|
||||
sa_family_t sa_family; /**< Address family */
|
||||
char sa_data[SOCKADDR_MAX_DATA_LEN]; /**< Socket address (variable length data) */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Implementation based socket address table.
|
||||
* @extends struct sockaddr
|
||||
*/
|
||||
struct __attribute__((packed)) sockaddr_storage {
|
||||
sa_family_t ss_family; ///< Address family
|
||||
char ss_data[14]; ///< address data
|
||||
struct sockaddr_storage {
|
||||
sa_family_t ss_family; /**< Address family */
|
||||
uint8_t ss_data[SOCKADDR_MAX_DATA_LEN]; /**< Socket address */
|
||||
};
|
||||
|
||||
/*
|
||||
* Omitted from original specification for now are struct msghdr,
|
||||
* struct cmesghdr, and struct linger and all related defines
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief *level* value for getsockopt() or setsockopt().
|
||||
*/
|
||||
#define SOL_SOCKET 1 ///< Options to be accessed at socket level, not
|
||||
///< protocol level.
|
||||
|
||||
/**
|
||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
||||
*/
|
||||
#define SO_ACCEPTCONN 1 ///< Socket is accepting connections.
|
||||
|
||||
/**
|
||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
||||
*/
|
||||
#define SO_BROADCAST 2 ///< Transmission of broadcast messages is supported.
|
||||
|
||||
/**
|
||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
||||
*/
|
||||
#define SO_DEBUG 3 ///< Debugging information is being recorded.
|
||||
|
||||
/**
|
||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
||||
*/
|
||||
#define SO_DONTROUTE 4 ///< Bypass normal routing.
|
||||
|
||||
/**
|
||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
||||
*/
|
||||
#define SO_ERROR 5 ///< Socket error status.
|
||||
|
||||
/**
|
||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
||||
*/
|
||||
#define SO_KEEPALIVE 6 ///< Connections are kept alive with periodic messages.
|
||||
|
||||
/**
|
||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
||||
*/
|
||||
#define SO_OOBINLINE 7 ///< Out-of-band data is transmitted in line.
|
||||
|
||||
/**
|
||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
||||
*/
|
||||
#define SO_RCVBUF 8 ///< Receive buffer size.
|
||||
|
||||
/**
|
||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
||||
*/
|
||||
#define SO_RCVLOWAT 9 ///< Receive "low water mark".
|
||||
|
||||
/**
|
||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
||||
*/
|
||||
#define SO_RCVTIMEO 10 ///< Receive timeout.
|
||||
|
||||
/**
|
||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
||||
*/
|
||||
#define SO_REUSEADDR 11 ///< Reuse of local addresses is supported.
|
||||
|
||||
/**
|
||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
||||
*/
|
||||
#define SO_SNDBUF 12 ///< Send buffer size.
|
||||
|
||||
/**
|
||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
||||
*/
|
||||
#define SO_SNDLOWAT 13 ///< Send "low water mark".
|
||||
|
||||
/**
|
||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
||||
*/
|
||||
#define SO_SNDTIMEO 14 ///< Send timeout.
|
||||
|
||||
/**
|
||||
* @brief *option_name* value for getsockopt() or setsockopt()
|
||||
*/
|
||||
#define SO_TYPE 15 ///< Socket type.
|
||||
|
||||
#define SOMAXCONN 16 ///< Maximum *backlog* size for listen()
|
||||
|
||||
/**
|
||||
* @brief *how* value for shutdown()
|
||||
*/
|
||||
#define SHUT_WR 1 ///< Disables further send operations.
|
||||
|
||||
/**
|
||||
* @brief *how* value for shutdown()
|
||||
*/
|
||||
#define SHUT_RD 2 ///< Disables further receive operations.
|
||||
|
||||
/**
|
||||
* @brief *how* value for shutdown()
|
||||
*/
|
||||
#define SHUT_RDWR 3 ///< Disables further send and receive operations.
|
||||
|
||||
/**
|
||||
* @brief Accept a new connection on a socket
|
||||
@ -260,27 +212,56 @@ int bind(int socket, const struct sockaddr *address,
|
||||
int connect(int socket, const struct sockaddr *address, socklen_t address_len);
|
||||
|
||||
/**
|
||||
* @brief Get the socket options.
|
||||
* @brief Get the name of the peer socket.
|
||||
* @details The getpeername() function shall retrieve the peer address of the specified socket,
|
||||
* store this address in the sockaddr structure pointed to by the @p address argument,
|
||||
* and store the length of this address in the object pointed to by the @p address_len
|
||||
* argument.
|
||||
*
|
||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockopt.html">
|
||||
* The Open Group Base Specification Issue 7, getsockopt
|
||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpeername.html">
|
||||
* The Open Group Base Specification Issue 7, getpeername
|
||||
* </a>
|
||||
*
|
||||
* @param[in] socket Specifies the file descriptor associated with the socket.
|
||||
* @param[in] level Protocol level this option applies to. Valid values
|
||||
* are defined in <sys/socket.h>, prefixed with
|
||||
* ``SOL_``.
|
||||
* @param[in] option_name Defines the option to get. Valid values are defined
|
||||
* in <sys/socket.h>, prefixed with ``SO_``.
|
||||
* @param[out] option_value Buffer to write the current value of the socket
|
||||
* option into.
|
||||
* @param[out] option_len Length of the option value in byte.
|
||||
*
|
||||
* @return Upon successful completion, getsockopt() shall return 0; otherwise,
|
||||
* @param[in] socket Specifies the file descriptor associated with the
|
||||
* socket.
|
||||
* @param[out] address Points to a sockaddr structure containing the peer
|
||||
* address. The length and format of the address depend
|
||||
* on the address family of the socket.
|
||||
* @param[in,out] address_len Specifies the length of the sockaddr structure on input and the
|
||||
* length of the stored address on output. If the address is greater
|
||||
* than the length of the supplied sockaddr structure, the stored
|
||||
* address shal be truncated.
|
||||
* @return Upon successful completion, getpeername() shall return 0; otherwise,
|
||||
* -1 shall be returned and errno set to indicate the error.
|
||||
*/
|
||||
int getsockopt(int socket, int level, int option_name,
|
||||
void *__restrict option_value, socklen_t *__restrict option_len);
|
||||
int getpeername(int socket, struct sockaddr *__restrict address,
|
||||
socklen_t *__restrict address_len);
|
||||
|
||||
/**
|
||||
* @brief Get the socket name.
|
||||
* @details The getsockname() function shall retrieve the locally-bound name of the specified
|
||||
* socket, store this address in the sockaddr structure pointed to by the @p address
|
||||
* argument, and store the length of this address in the object pointed to by the
|
||||
* @p address_len argument.
|
||||
*
|
||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getsockname.html">
|
||||
* The Open Group Base Specification Issue 7, getsockname
|
||||
* </a>
|
||||
*
|
||||
* @param[in] socket Specifies the file descriptor associated with the
|
||||
* socket.
|
||||
* @param[out] address Points to a sockaddr structure containing the peer
|
||||
* address. The length and format of the address depend
|
||||
* on the address family of the socket.
|
||||
* @param[in,out] address_len Specifies the length of the sockaddr structure on input and the
|
||||
* length of the stored address on output. If the address is greater
|
||||
* than the length of the supplied sockaddr structure, the stored
|
||||
* address shal be truncated.
|
||||
* @return Upon successful completion, getsockname() shall return 0; otherwise,
|
||||
* -1 shall be returned and errno set to indicate the error.
|
||||
*/
|
||||
int getsockname(int socket, struct sockaddr *__restrict address,
|
||||
socklen_t *__restrict address_len);
|
||||
|
||||
/**
|
||||
* @brief Listen for socket connections and limit the queue of incoming
|
||||
@ -396,9 +377,9 @@ ssize_t send(int socket, const void *buffer, size_t length, int flags);
|
||||
* @details Shall send a message through a connection-mode or
|
||||
* connectionless-mode socket. If the socket is a connectionless-mode
|
||||
* socket, the message shall be sent to the address specified by
|
||||
* *dest_addr* if no pre-specified peer address has been set. If a
|
||||
* @p address if no pre-specified peer address has been set. If a
|
||||
* peer address has been pre-specified, either the message shall be
|
||||
* sent to the address specified by *dest_addr* (overriding the
|
||||
* sent to the address specified by @p address (overriding the
|
||||
* pre-specified peer address), or the function shall return -1 and
|
||||
* set errno to EISCONN.
|
||||
*
|
||||
@ -406,45 +387,23 @@ ssize_t send(int socket, const void *buffer, size_t length, int flags);
|
||||
* The Open Group Base Specification Issue 7, sendto
|
||||
* </a>
|
||||
*
|
||||
* @param[in] socket Specifies the socket file descriptor.
|
||||
* @param[in] message Points to the buffer containing the message to send.
|
||||
* @param[in] length Specifies the length of the message in bytes.
|
||||
* @param[in] flags Specifies the type of message reception. Support
|
||||
* for values other than 0 is not implemented yet.
|
||||
* @param[in] dest_addr Points to a sockaddr structure containing the
|
||||
* destination address. The length and format of the
|
||||
* address depend on the address family of the socket.
|
||||
* @param[in] dest_len Specifies the length of the sockaddr structure pointed
|
||||
* to by the *dest_addr* argument.
|
||||
* @param[in] socket Specifies the socket file descriptor.
|
||||
* @param[in] buffer Points to the buffer containing the message to send.
|
||||
* @param[in] length Specifies the length of the message in bytes.
|
||||
* @param[in] flags Specifies the type of message reception. Support
|
||||
* for values other than 0 is not implemented yet.
|
||||
* @param[in] address Points to a sockaddr structure containing the
|
||||
* destination address. The length and format of the
|
||||
* address depend on the address family of the socket.
|
||||
* @param[in] address_len Specifies the length of the sockaddr structure pointed
|
||||
* to by the @p address argument.
|
||||
*
|
||||
* @return Upon successful completion, send() shall return the number of bytes
|
||||
* sent. Otherwise, -1 shall be returned and errno set to indicate the
|
||||
* error.
|
||||
*/
|
||||
ssize_t sendto(int socket, const void *message, size_t length, int flags,
|
||||
const struct sockaddr *dest_addr, socklen_t dest_len);
|
||||
|
||||
/**
|
||||
* @brief Set the socket options.
|
||||
*
|
||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html">
|
||||
* The Open Group Base Specification Issue 7, setsockopt
|
||||
* </a>
|
||||
*
|
||||
* @param[in] socket Specifies the file descriptor associated with the socket.
|
||||
* @param[in] level Protocol level this option applies to. Valid values
|
||||
* are defined in <sys/socket.h>, prefixed with
|
||||
* ``SOL_``.
|
||||
* @param[in] option_name Defines the option to set. Valid values are defined
|
||||
* in <sys/socket.h>, prefixed with ``SO_``.
|
||||
* @param[in] option_value Value for the option to set.
|
||||
* @param[in] option_len Length of the option value in byte.
|
||||
*
|
||||
* @return Upon successful completion, setsockopt() shall return 0; otherwise,
|
||||
* -1 shall be returned and errno set to indicate the error.
|
||||
*/
|
||||
int setsockopt(int socket, int level, int option_name, const void *option_value,
|
||||
socklen_t option_len);
|
||||
ssize_t sendto(int socket, const void *buffer, size_t length, int flags,
|
||||
const struct sockaddr *address, socklen_t address_len);
|
||||
|
||||
/**
|
||||
* @brief Create an endpoint for communication.
|
||||
@ -469,6 +428,34 @@ int setsockopt(int socket, int level, int option_name, const void *option_value,
|
||||
*/
|
||||
int socket(int domain, int type, int protocol);
|
||||
|
||||
/**
|
||||
* @todo implement out these functions
|
||||
* @{
|
||||
*/
|
||||
static inline int getsockopt(int socket, int level, int option_name, void *option_value,
|
||||
socklen_t *option_len)
|
||||
{
|
||||
(void)socket;
|
||||
(void)level;
|
||||
(void)option_name;
|
||||
(void)option_value;
|
||||
(void)option_len;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int setsockopt(int socket, int level, int option_name, const void *option_value,
|
||||
socklen_t option_len)
|
||||
{
|
||||
(void)socket;
|
||||
(void)level;
|
||||
(void)option_name;
|
||||
(void)option_value;
|
||||
(void)option_len;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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
|
||||
* @brief Providing values for in6addr_any and in6addr_loopback.
|
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
*/
|
||||
#include <netinet/in.h>
|
||||
|
||||
const struct sockaddr_in6 in6addr_any = {{AF_INET6, 0, 0, IN6ADDR_ANY_INIT}, 0};
|
||||
const struct sockaddr_in6 in6addr_loopback = {{
|
||||
AF_INET6, 0, 0, IN6ADDR_LOOPBACK_INIT
|
||||
}, 0
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
@ -1,154 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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
|
||||
* @brief Providing implementation for POSIX socket wrapper.
|
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @todo
|
||||
*/
|
||||
|
||||
#include "sys/socket.h"
|
||||
|
||||
int flagless_send(int fd, const void *buf, size_t len)
|
||||
{
|
||||
(void)fd;
|
||||
(void)buf;
|
||||
(void)len;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int flagless_recv(int fd, void *buf, size_t len)
|
||||
{
|
||||
return (int)socket_base_recv(fd, buf, (uint32_t)len, 0);
|
||||
}
|
||||
|
||||
int socket(int domain, int type, int protocol)
|
||||
{
|
||||
(void)domain;
|
||||
(void)type;
|
||||
(void)protocol;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int accept(int socket, struct sockaddr *restrict address,
|
||||
socklen_t *restrict address_len)
|
||||
{
|
||||
(void)socket;
|
||||
(void)address;
|
||||
(void)address_len;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int bind(int socket, const struct sockaddr *address, socklen_t address_len)
|
||||
{
|
||||
(void)socket;
|
||||
(void)address;
|
||||
(void)address_len;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int connect(int socket, const struct sockaddr *address, socklen_t address_len)
|
||||
{
|
||||
(void)socket;
|
||||
(void)address;
|
||||
(void)address_len;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getsockopt(int socket, int level, int option_name,
|
||||
void *restrict option_value, socklen_t *restrict option_len)
|
||||
{
|
||||
// TODO
|
||||
(void) socket;
|
||||
(void) level;
|
||||
(void) option_name;
|
||||
(void) option_value;
|
||||
(void) option_len;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int listen(int socket, int backlog)
|
||||
{
|
||||
(void)socket;
|
||||
(void)backlog;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t recv(int socket, void *buffer, size_t length, int flags)
|
||||
{
|
||||
(void)socket;
|
||||
(void)buffer;
|
||||
(void)length;
|
||||
(void)flags;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags,
|
||||
struct sockaddr *restrict address,
|
||||
socklen_t *restrict address_len)
|
||||
{
|
||||
(void)socket;
|
||||
(void)buffer;
|
||||
(void)length;
|
||||
(void)flags;
|
||||
(void)address;
|
||||
(void)address_len;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t send(int socket, const void *buffer, size_t length, int flags)
|
||||
{
|
||||
(void)socket;
|
||||
(void)buffer;
|
||||
(void)length;
|
||||
(void)flags;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t sendto(int socket, const void *message, size_t length, int flags,
|
||||
const struct sockaddr *dest_addr, socklen_t dest_len)
|
||||
{
|
||||
// TODO
|
||||
(void)socket;
|
||||
(void)message;
|
||||
(void)length;
|
||||
(void)flags;
|
||||
(void)dest_addr;
|
||||
(void)dest_len;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int setsockopt(int socket, int level, int option_name, const void *option_value,
|
||||
socklen_t option_len)
|
||||
{
|
||||
// TODO
|
||||
(void) socket;
|
||||
(void) level;
|
||||
(void) option_name;
|
||||
(void) option_value;
|
||||
(void) option_len;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
@ -1 +1,3 @@
|
||||
MODULE = posix_sockets
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
@ -7,8 +7,8 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pnet Network related POSIX wrapper of RIOT
|
||||
* @brief Network related POSIX header files
|
||||
* @defgroup posix_sockets POSIX sockets
|
||||
* @brief POSIX socket wrapper of RIOT's @ref net_conn
|
||||
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/">
|
||||
* The Open Group Specifications Issue 7
|
||||
* </a>
|
890
sys/posix/sockets/posix_sockets.c
Normal file
890
sys/posix/sockets/posix_sockets.c
Normal file
@ -0,0 +1,890 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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
|
||||
* @brief Providing implementation for POSIX socket wrapper.
|
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
* @todo
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fd.h"
|
||||
#include "mutex.h"
|
||||
#include "net/conn.h"
|
||||
#include "net/ipv4/addr.h"
|
||||
#include "net/ipv6/addr.h"
|
||||
#include "random.h"
|
||||
|
||||
#include "sys/socket.h"
|
||||
#include "netinet/in.h"
|
||||
|
||||
#define SOCKET_POOL_SIZE (4)
|
||||
|
||||
/**
|
||||
* @brief Unitfied connection type.
|
||||
*/
|
||||
typedef union {
|
||||
/* is not supposed to be used */
|
||||
/* cppcheck-suppress unusedStructMember */
|
||||
int undef; /**< for case that no connection module is present */
|
||||
#ifdef MODULE_CONN_IP
|
||||
conn_ip_t raw; /**< raw IP connection */
|
||||
#endif /* MODULE_CONN_IP */
|
||||
#ifdef MODULE_CONN_TCP
|
||||
conn_tcp_t tcp; /**< TCP connection */
|
||||
#endif /* MODULE_CONN_TCP */
|
||||
#ifdef MODULE_CONN_UDP
|
||||
conn_udp_t udp; /**< UDP connection */
|
||||
#endif /* MODULE_CONN_UDP */
|
||||
} socket_conn_t;
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
sa_family_t domain;
|
||||
int type;
|
||||
int protocol;
|
||||
bool bound;
|
||||
socket_conn_t conn;
|
||||
} socket_t;
|
||||
|
||||
socket_t _pool[SOCKET_POOL_SIZE];
|
||||
mutex_t _pool_mutex = MUTEX_INIT;
|
||||
|
||||
const struct sockaddr_in6 in6addr_any = {AF_INET6, 0, 0, IN6ADDR_ANY_INIT, 0};
|
||||
const struct sockaddr_in6 in6addr_loopback = {
|
||||
AF_INET6, 0, 0, IN6ADDR_LOOPBACK_INIT, 0
|
||||
};
|
||||
|
||||
static socket_t *_get_free_socket(void)
|
||||
{
|
||||
for (int i = 0; i < SOCKET_POOL_SIZE; i++) {
|
||||
if (_pool[i].domain == AF_UNSPEC) {
|
||||
return &_pool[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static socket_t *_get_socket(int fd)
|
||||
{
|
||||
for (int i = 0; i < SOCKET_POOL_SIZE; i++) {
|
||||
if (_pool[i].fd == fd) {
|
||||
return &_pool[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int _choose_ipproto(int type, int protocol)
|
||||
{
|
||||
switch (type) {
|
||||
#ifdef MODULE_CONN_TCP
|
||||
case SOCK_STREAM:
|
||||
if ((protocol == 0) || (protocol == IPPROTO_TCP)) {
|
||||
return protocol;
|
||||
}
|
||||
else {
|
||||
errno = EPROTOTYPE;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef MODULE_CONN_UDP
|
||||
case SOCK_DGRAM:
|
||||
if ((protocol == 0) || (protocol == IPPROTO_UDP)) {
|
||||
return protocol;
|
||||
}
|
||||
else {
|
||||
errno = EPROTOTYPE;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef MODULE_CONN_IP
|
||||
case SOCK_RAW:
|
||||
return protocol;
|
||||
#endif
|
||||
default:
|
||||
(void)protocol;
|
||||
break;
|
||||
}
|
||||
errno = EPROTONOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline void _htons_port(uint16_t *port)
|
||||
{
|
||||
*port = htons(*port);
|
||||
}
|
||||
|
||||
static inline ipv4_addr_t *_in_addr_ptr(struct sockaddr_storage *addr)
|
||||
{
|
||||
return (ipv4_addr_t *)(&((struct sockaddr_in *)addr)->sin_addr);
|
||||
}
|
||||
|
||||
static inline uint16_t *_in_port_ptr(struct sockaddr_storage *addr)
|
||||
{
|
||||
return &((struct sockaddr_in *)addr)->sin_port;
|
||||
}
|
||||
|
||||
static inline ipv6_addr_t *_in6_addr_ptr(struct sockaddr_storage *addr)
|
||||
{
|
||||
return (ipv6_addr_t *)(&((struct sockaddr_in6 *)addr)->sin6_addr);
|
||||
}
|
||||
|
||||
static inline uint16_t *_in6_port_ptr(struct sockaddr_storage *addr)
|
||||
{
|
||||
return &((struct sockaddr_in6 *)addr)->sin6_port;
|
||||
}
|
||||
|
||||
static inline socklen_t _addr_truncate(struct sockaddr *out, socklen_t out_len,
|
||||
struct sockaddr_storage *in, socklen_t target_size)
|
||||
{
|
||||
out_len = (out_len < target_size) ? out_len : target_size;
|
||||
memcpy(out, in, out_len);
|
||||
return out_len;
|
||||
}
|
||||
|
||||
static inline int _get_data_from_sockaddr(const struct sockaddr *address, size_t address_len,
|
||||
void **addr, size_t *addr_len, uint16_t *port)
|
||||
{
|
||||
switch (address->sa_family) {
|
||||
case AF_INET:
|
||||
if (address_len < sizeof(struct sockaddr_in)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
struct sockaddr_in *in_addr = (struct sockaddr_in *)address;
|
||||
*addr = &in_addr->sin_addr;
|
||||
*addr_len = sizeof(ipv4_addr_t);
|
||||
/* XXX sin_port is in network byteorder */
|
||||
*port = ntohs(in_addr->sin_port);
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (address_len < sizeof(struct sockaddr_in6)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)address;
|
||||
*addr = &in6_addr->sin6_addr;
|
||||
*addr_len = sizeof(ipv6_addr_t);
|
||||
/* XXX sin6_port is in network byteorder */
|
||||
*port = ntohs(in6_addr->sin6_port);
|
||||
break;
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int socket_close(int socket)
|
||||
{
|
||||
socket_t *s;
|
||||
int res = 0;
|
||||
if ((unsigned)(socket - 1) > (SOCKET_POOL_SIZE - 1)) {
|
||||
return -1;
|
||||
}
|
||||
mutex_lock(&_pool_mutex);
|
||||
s = &_pool[socket];
|
||||
if (s->bound) {
|
||||
switch (s->domain) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
switch (s->type) {
|
||||
#ifdef MODULE_CONN_UDP
|
||||
case SOCK_DGRAM:
|
||||
conn_udp_close(&s->conn.udp);
|
||||
break;
|
||||
#endif
|
||||
#ifdef MODULE_CONN_IP
|
||||
case SOCK_RAW:
|
||||
conn_ip_close(&s->conn.raw);
|
||||
break;
|
||||
#endif
|
||||
#ifdef MODULE_CONN_TCP
|
||||
case SOCK_STREAM:
|
||||
conn_tcp_close(&s->conn.tcp);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
errno = EOPNOTSUPP;
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
s->domain = AF_UNSPEC;
|
||||
mutex_unlock(&_pool_mutex);
|
||||
return res;
|
||||
}
|
||||
|
||||
static ssize_t socket_read(int socket, void *buf, size_t n)
|
||||
{
|
||||
return recv(socket, buf, n, 0);
|
||||
}
|
||||
|
||||
static ssize_t socket_write(int socket, const void *buf, size_t n)
|
||||
{
|
||||
return send(socket, buf, n, 0);
|
||||
}
|
||||
|
||||
int socket(int domain, int type, int protocol)
|
||||
{
|
||||
int res = 0;
|
||||
socket_t *s;
|
||||
mutex_lock(&_pool_mutex);
|
||||
s = _get_free_socket();
|
||||
if (s == NULL) {
|
||||
errno = ENFILE;
|
||||
mutex_unlock(&_pool_mutex);
|
||||
return -1;
|
||||
}
|
||||
switch (domain) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
s->domain = domain;
|
||||
s->type = type;
|
||||
if ((s->protocol = _choose_ipproto(type, protocol)) < 0) {
|
||||
res = -1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
(void)type;
|
||||
(void)protocol;
|
||||
errno = EAFNOSUPPORT;
|
||||
res = -1;
|
||||
}
|
||||
if (res == 0) {
|
||||
/* TODO: add read and write */
|
||||
int fd = fd_new(s - _pool, socket_read, socket_write, socket_close);
|
||||
if (fd < 0) {
|
||||
errno = ENFILE;
|
||||
res = -1;
|
||||
}
|
||||
else {
|
||||
s->fd = res = fd;
|
||||
}
|
||||
}
|
||||
s->bound = false;
|
||||
mutex_unlock(&_pool_mutex);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int accept(int socket, struct sockaddr *restrict address,
|
||||
socklen_t *restrict address_len)
|
||||
{
|
||||
socket_t *s, *new_s = NULL;
|
||||
int res = 0;
|
||||
/* May be kept unassigned if no conn module is available */
|
||||
/* cppcheck-suppress unassignedVariable */
|
||||
struct sockaddr_storage tmp;
|
||||
void *addr;
|
||||
uint16_t *port;
|
||||
socklen_t tmp_len;
|
||||
mutex_lock(&_pool_mutex);
|
||||
s = _get_socket(socket);
|
||||
if (s == NULL) {
|
||||
mutex_unlock(&_pool_mutex);
|
||||
errno = ENOTSOCK;
|
||||
return -1;
|
||||
}
|
||||
if (!s->bound) {
|
||||
mutex_unlock(&_pool_mutex);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
switch (s->domain) {
|
||||
case AF_INET:
|
||||
addr = _in_addr_ptr(&tmp);
|
||||
port = _in_port_ptr(&tmp);
|
||||
tmp_len = sizeof(struct sockaddr_in);
|
||||
break;
|
||||
case AF_INET6:
|
||||
addr = _in6_addr_ptr(&tmp);
|
||||
port = _in6_port_ptr(&tmp);
|
||||
tmp_len = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
default:
|
||||
(void)address;
|
||||
(void)address_len;
|
||||
(void)new_s;
|
||||
(void)tmp;
|
||||
(void)addr;
|
||||
(void)port;
|
||||
(void)tmp_len;
|
||||
errno = EPROTO;
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
switch (s->type) {
|
||||
#ifdef MODULE_CONN_TCP
|
||||
case SOCK_STREAM:
|
||||
new_s = _get_free_socket();
|
||||
if (new_s == NULL) {
|
||||
errno = ENFILE;
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
if ((res = conn_tcp_accept(&s->conn.tcp, &new_s->conn.tcp)) < 0) {
|
||||
errno = -res;
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
else if ((address != NULL) && (address_len != NULL)) {
|
||||
/* TODO: add read and write */
|
||||
int fd = fd_new(new_s - _pool, NULL, NULL, socket_close);
|
||||
if (fd < 0) {
|
||||
errno = ENFILE;
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
new_s->fd = res = fd;
|
||||
}
|
||||
new_s->domain = s->domain;
|
||||
new_s->type = s->type;
|
||||
new_s->protocol = s->protocol;
|
||||
tmp.ss_family = s->domain;
|
||||
if ((res = conn_tcp_getpeeraddr(&s->conn.tcp, addr, port)) < 0) {
|
||||
errno = -res;
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
_htons_port(port); /* XXX: sin(6)_port is supposed to be network byte
|
||||
* order */
|
||||
*address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
errno = EOPNOTSUPP;
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&_pool_mutex);
|
||||
return res;
|
||||
}
|
||||
|
||||
int bind(int socket, const struct sockaddr *address, socklen_t address_len)
|
||||
{
|
||||
socket_t *s;
|
||||
int res = 0;
|
||||
void *addr;
|
||||
size_t addr_len;
|
||||
uint16_t port;
|
||||
mutex_lock(&_pool_mutex);
|
||||
s = _get_socket(socket);
|
||||
mutex_unlock(&_pool_mutex);
|
||||
if (s == NULL) {
|
||||
errno = ENOTSOCK;
|
||||
return -1;
|
||||
}
|
||||
if (address->sa_family != s->domain) {
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
if (_get_data_from_sockaddr(address, address_len, &addr, &addr_len, &port) < 0) {
|
||||
return -1;
|
||||
}
|
||||
switch (s->type) {
|
||||
#ifdef MODULE_CONN_IP
|
||||
case SOCK_RAW:
|
||||
(void)port;
|
||||
if ((res = conn_ip_create(&s->conn.raw, addr, addr_len, s->domain, s->protocol)) < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef MODULE_CONN_TCP
|
||||
case SOCK_STREAM:
|
||||
if ((res = conn_tcp_create(&s->conn.tcp, addr, addr_len, s->domain, port)) < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef MODULE_CONN_UDP
|
||||
case SOCK_DGRAM:
|
||||
if ((res = conn_udp_create(&s->conn.udp, addr, addr_len, s->domain, port)) < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void)addr;
|
||||
(void)addr_len;
|
||||
(void)port;
|
||||
(void)res;
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
s->bound = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int connect(int socket, const struct sockaddr *address, socklen_t address_len)
|
||||
{
|
||||
socket_t *s;
|
||||
int res = 0;
|
||||
void *addr;
|
||||
size_t addr_len;
|
||||
uint16_t port;
|
||||
mutex_lock(&_pool_mutex);
|
||||
s = _get_socket(socket);
|
||||
mutex_unlock(&_pool_mutex);
|
||||
if (s == NULL) {
|
||||
errno = ENOTSOCK;
|
||||
return -1;
|
||||
}
|
||||
if (!s->bound) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (address->sa_family != s->domain) {
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
if (_get_data_from_sockaddr(address, address_len, &addr, &addr_len, &port) < 0) {
|
||||
return -1;
|
||||
}
|
||||
switch (s->type) {
|
||||
#ifdef MODULE_CONN_TCP
|
||||
case SOCK_STREAM:
|
||||
/* XXX sin_port is in network byteorder */
|
||||
if ((res = conn_tcp_connect(&s->conn.tcp, addr, addr_len, port)) < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void)res;
|
||||
errno = EPROTOTYPE;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getpeername(int socket, struct sockaddr *__restrict address,
|
||||
socklen_t *__restrict address_len)
|
||||
{
|
||||
socket_t *s;
|
||||
int res = 0;
|
||||
/* May be kept unassigned if no conn module is available */
|
||||
/* cppcheck-suppress unassignedVariable */
|
||||
struct sockaddr_storage tmp;
|
||||
void *addr;
|
||||
uint16_t *port;
|
||||
socklen_t tmp_len;
|
||||
mutex_lock(&_pool_mutex);
|
||||
s = _get_socket(socket);
|
||||
mutex_unlock(&_pool_mutex);
|
||||
if (s == NULL) {
|
||||
errno = ENOTSOCK;
|
||||
return -1;
|
||||
}
|
||||
switch (s->domain) {
|
||||
case AF_INET:
|
||||
addr = _in_addr_ptr(&tmp);
|
||||
port = _in_port_ptr(&tmp);
|
||||
tmp_len = sizeof(struct sockaddr_in);
|
||||
break;
|
||||
case AF_INET6:
|
||||
addr = _in6_addr_ptr(&tmp);
|
||||
port = _in6_port_ptr(&tmp);
|
||||
tmp_len = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
default:
|
||||
(void)address;
|
||||
(void)address_len;
|
||||
(void)tmp;
|
||||
(void)addr;
|
||||
(void)port;
|
||||
(void)tmp_len;
|
||||
(void)res;
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (*address_len != tmp_len) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
switch (s->type) {
|
||||
#ifdef MODULE_CONN_TCP
|
||||
case SOCK_STREAM:
|
||||
if ((res = conn_tcp_getpeeraddr(&s->conn.tcp, addr, port)) < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
errno = ENOTCONN;
|
||||
return -1;
|
||||
}
|
||||
tmp.ss_family = s->domain;
|
||||
_htons_port(port); /* XXX: sin(6)_port is supposed to be network byte
|
||||
* order */
|
||||
*address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getsockname(int socket, struct sockaddr *__restrict address,
|
||||
socklen_t *__restrict address_len)
|
||||
{
|
||||
socket_t *s;
|
||||
int res = 0;
|
||||
/* May be kept unassigned if no conn module is available */
|
||||
/* cppcheck-suppress unassignedVariable */
|
||||
struct sockaddr_storage tmp;
|
||||
void *addr;
|
||||
uint16_t *port;
|
||||
socklen_t tmp_len;
|
||||
mutex_lock(&_pool_mutex);
|
||||
s = _get_socket(socket);
|
||||
mutex_unlock(&_pool_mutex);
|
||||
if (s == NULL) {
|
||||
errno = ENOTSOCK;
|
||||
return -1;
|
||||
}
|
||||
if (!s->bound) {
|
||||
memset(address, 0, *address_len);
|
||||
return 0;
|
||||
}
|
||||
switch (s->domain) {
|
||||
case AF_INET:
|
||||
addr = _in_addr_ptr(&tmp);
|
||||
port = _in_port_ptr(&tmp);
|
||||
tmp_len = sizeof(struct sockaddr_in);
|
||||
break;
|
||||
case AF_INET6:
|
||||
addr = _in6_addr_ptr(&tmp);
|
||||
port = _in6_port_ptr(&tmp);
|
||||
tmp_len = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
default:
|
||||
(void)address;
|
||||
(void)address_len;
|
||||
(void)tmp;
|
||||
(void)addr;
|
||||
(void)port;
|
||||
(void)tmp_len;
|
||||
(void)res;
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (*address_len != tmp_len) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
switch (s->type) {
|
||||
#ifdef MODULE_CONN_UDP
|
||||
case SOCK_DGRAM:
|
||||
if ((res = conn_udp_getlocaladdr(&s->conn.udp, addr, port)) < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef MODULE_CONN_IP
|
||||
case SOCK_RAW:
|
||||
if ((res = conn_ip_getlocaladdr(&s->conn.raw, addr)) < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef MODULE_CONN_TCP
|
||||
case SOCK_STREAM:
|
||||
if ((res = conn_tcp_getlocaladdr(&s->conn.tcp, addr, port)) < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
tmp.ss_family = AF_INET;
|
||||
_htons_port(port); /* XXX: sin(6)_port is supposed to be network byte
|
||||
* order */
|
||||
*address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int listen(int socket, int backlog)
|
||||
{
|
||||
socket_t *s;
|
||||
int res = 0;
|
||||
mutex_lock(&_pool_mutex);
|
||||
s = _get_socket(socket);
|
||||
mutex_unlock(&_pool_mutex);
|
||||
if (!s->bound) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
switch (s->domain) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
switch (s->type) {
|
||||
#ifdef MODULE_CONN_TCP
|
||||
case SOCK_STREAM:
|
||||
if ((res = conn_tcp_listen(&s->conn.tcp, backlog)) < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
(void)backlog;
|
||||
(void)res;
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t recv(int socket, void *buffer, size_t length, int flags)
|
||||
{
|
||||
return recvfrom(socket, buffer, length, flags, NULL, NULL);
|
||||
}
|
||||
|
||||
ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags,
|
||||
struct sockaddr *restrict address,
|
||||
socklen_t *restrict address_len)
|
||||
{
|
||||
socket_t *s;
|
||||
int res = 0;
|
||||
/* May be kept unassigned if no conn module is available */
|
||||
/* cppcheck-suppress unassignedVariable */
|
||||
struct sockaddr_storage tmp;
|
||||
void *addr;
|
||||
size_t addr_len;
|
||||
uint16_t *port;
|
||||
socklen_t tmp_len;
|
||||
(void)flags;
|
||||
mutex_lock(&_pool_mutex);
|
||||
s = _get_socket(socket);
|
||||
mutex_unlock(&_pool_mutex);
|
||||
if (s == NULL) {
|
||||
errno = ENOTSOCK;
|
||||
return -1;
|
||||
}
|
||||
if (!s->bound) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
switch (s->domain) {
|
||||
case AF_INET:
|
||||
addr = _in_addr_ptr(&tmp);
|
||||
port = _in_port_ptr(&tmp);
|
||||
addr_len = sizeof(ipv4_addr_t);
|
||||
tmp_len = sizeof(struct sockaddr_in);
|
||||
break;
|
||||
case AF_INET6:
|
||||
addr = _in6_addr_ptr(&tmp);
|
||||
port = _in6_port_ptr(&tmp);
|
||||
addr_len = sizeof(ipv6_addr_t);
|
||||
tmp_len = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
default:
|
||||
(void)buffer;
|
||||
(void)length;
|
||||
(void)address;
|
||||
(void)address_len;
|
||||
(void)tmp;
|
||||
(void)addr;
|
||||
(void)port;
|
||||
(void)tmp_len;
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
switch (s->type) {
|
||||
#ifdef MODULE_CONN_UDP
|
||||
case SOCK_DGRAM:
|
||||
if ((res = conn_udp_recvfrom(&s->conn.udp, buffer, length, addr, &addr_len,
|
||||
port)) < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef MODULE_CONN_IP
|
||||
case SOCK_RAW:
|
||||
if ((res = conn_ip_recvfrom(&s->conn.raw, buffer, length, addr, &addr_len)) < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef MODULE_CONN_TCP
|
||||
case SOCK_STREAM:
|
||||
if ((res = conn_tcp_recv(&s->conn.tcp, buffer, length)) < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
if ((res = conn_tcp_getpeeraddr(&s->conn.tcp, addr, port)) < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void)addr_len;
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
if ((address != NULL) && (address_len != NULL)) {
|
||||
tmp.ss_family = s->domain;
|
||||
_htons_port(port); /* XXX: sin_port is supposed to be network byte
|
||||
* order */
|
||||
*address_len = _addr_truncate(address, *address_len, &tmp, tmp_len);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
ssize_t send(int socket, const void *buffer, size_t length, int flags)
|
||||
{
|
||||
return sendto(socket, buffer, length, flags, NULL, 0);
|
||||
}
|
||||
|
||||
ssize_t sendto(int socket, const void *buffer, size_t length, int flags,
|
||||
const struct sockaddr *address, socklen_t address_len)
|
||||
{
|
||||
socket_t *s;
|
||||
int res = 0;
|
||||
void *addr = NULL;
|
||||
size_t addr_len = 0;
|
||||
uint16_t port = 0;
|
||||
(void)flags;
|
||||
mutex_lock(&_pool_mutex);
|
||||
s = _get_socket(socket);
|
||||
mutex_unlock(&_pool_mutex);
|
||||
if (s == NULL) {
|
||||
errno = ENOTSOCK;
|
||||
return -1;
|
||||
}
|
||||
if (address != NULL) {
|
||||
if (address->sa_family != s->domain) {
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
if (_get_data_from_sockaddr(address, address_len, &addr, &addr_len, &port) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
switch (s->type) {
|
||||
#ifdef MODULE_CONN_IP
|
||||
case SOCK_RAW:
|
||||
if ((address != NULL) && (s->bound)) {
|
||||
uint8_t src_addr[sizeof(ipv6_addr_t)];
|
||||
size_t src_len;
|
||||
int res = conn_ip_getlocaladdr(&s->conn.raw, src_addr);
|
||||
if (res < 0) {
|
||||
errno = ENOTSOCK; /* Something seems to be wrong with the socket */
|
||||
return -1;
|
||||
}
|
||||
src_len = (size_t)res;
|
||||
/* cppcheck bug? res is read below in l824 */
|
||||
/* cppcheck-suppress unreadVariable */
|
||||
res = conn_ip_sendto(buffer, length, src_addr, src_len, addr, addr_len, s->domain,
|
||||
s->protocol);
|
||||
}
|
||||
else if (address != NULL) {
|
||||
res = conn_ip_sendto(buffer, length, NULL, 0, addr, addr_len, s->domain,
|
||||
s->protocol);
|
||||
}
|
||||
else {
|
||||
errno = ENOTCONN;
|
||||
return -1;
|
||||
}
|
||||
if (res < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef MODULE_CONN_TCP
|
||||
case SOCK_STREAM:
|
||||
if (!s->bound) {
|
||||
errno = ENOTCONN;
|
||||
return -1;
|
||||
}
|
||||
if (address != NULL) {
|
||||
errno = EISCONN;
|
||||
return -1;
|
||||
}
|
||||
if ((res = conn_tcp_send(&s->conn.tcp, buffer, length)) < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef MODULE_CONN_UDP
|
||||
case SOCK_DGRAM:
|
||||
if ((address != NULL) && (s->bound)) {
|
||||
uint8_t src_addr[sizeof(ipv6_addr_t)];
|
||||
size_t src_len;
|
||||
uint16_t sport;
|
||||
int res = conn_udp_getlocaladdr(&s->conn.udp, src_addr, &sport);
|
||||
if (res < 0) {
|
||||
errno = ENOTSOCK; /* Something seems to be wrong with the socket */
|
||||
return -1;
|
||||
}
|
||||
src_len = (size_t)res;
|
||||
/* cppcheck bug? res is read below in l824 */
|
||||
/* cppcheck-suppress unreadVariable */
|
||||
res = conn_udp_sendto(buffer, length, src_addr, src_len, addr, addr_len, s->domain,
|
||||
sport, port);
|
||||
}
|
||||
else if (address != NULL) {
|
||||
uint16_t sport = (uint16_t)genrand_uint32_range(1LU << 10U, 1LU << 16U);
|
||||
res = conn_udp_sendto(buffer, length, NULL, 0, addr, addr_len, s->domain,
|
||||
sport, port);
|
||||
}
|
||||
else {
|
||||
errno = ENOTCONN;
|
||||
return -1;
|
||||
}
|
||||
if (res < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void)buffer;
|
||||
(void)length;
|
||||
errno = EOPNOTSUPP;
|
||||
return -1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
Loading…
Reference in New Issue
Block a user