Socket interface: Added getsockname[C() interfaces.
This commit is contained in:
parent
ac72978072
commit
ac543648b8
@ -116,6 +116,8 @@ struct sock_intf_s
|
||||
CODE void (*si_addref)(FAR struct socket *psock);
|
||||
CODE int (*si_bind)(FAR struct socket *psock,
|
||||
FAR const struct sockaddr *addr, socklen_t addrlen);
|
||||
CODE int (*si_getsockname)(FAR struct socket *psock,
|
||||
FAR struct sockaddr *addr, FAR socklen_t *addrlen);
|
||||
CODE int (*si_listen)(FAR struct socket *psock, int backlog);
|
||||
CODE int (*si_connect)(FAR struct socket *psock,
|
||||
FAR const struct sockaddr *addr, socklen_t addrlen);
|
||||
|
@ -69,8 +69,8 @@ int psock_local_bind(FAR struct socket *psock,
|
||||
(FAR const struct sockaddr_un *)addr;
|
||||
int namelen;
|
||||
|
||||
DEBUGASSERT(psock && psock->s_conn && unaddr &&
|
||||
unaddr->sun_family == AF_LOCAL &&
|
||||
DEBUGASSERT(psock != NULL && psock->s_conn != NULL &&
|
||||
unaddr != NULL && unaddr->sun_family == AF_LOCAL &&
|
||||
addrlen >= sizeof(sa_family_t));
|
||||
|
||||
conn = (FAR struct local_conn_s *)psock->s_conn;
|
||||
@ -79,7 +79,7 @@ int psock_local_bind(FAR struct socket *psock,
|
||||
|
||||
conn->lc_proto = psock->s_type;
|
||||
|
||||
/* No determine the type of the Unix domain socket by comparing the size
|
||||
/* Now determine the type of the Unix domain socket by comparing the size
|
||||
* of the address description.
|
||||
*/
|
||||
|
||||
|
@ -63,6 +63,8 @@ static sockcaps_t local_sockcaps(FAR struct socket *psock);
|
||||
static void local_addref(FAR struct socket *psock);
|
||||
static int local_bind(FAR struct socket *psock,
|
||||
FAR const struct sockaddr *addr, socklen_t addrlen);
|
||||
static int local_getsockname(FAR struct socket *psock,
|
||||
FAR struct sockaddr *addr, FAR socklen_t *addrlen);
|
||||
static int local_connect(FAR struct socket *psock,
|
||||
FAR const struct sockaddr *addr, socklen_t addrlen);
|
||||
static ssize_t local_send(FAR struct socket *psock, FAR const void *buf,
|
||||
@ -82,6 +84,7 @@ const struct sock_intf_s g_local_sockif =
|
||||
local_sockcaps, /* si_sockcaps */
|
||||
local_addref, /* si_addref */
|
||||
local_bind, /* si_bind */
|
||||
local_getsockname, /* si_getsockname */
|
||||
local_listen, /* si_listen */
|
||||
local_connect, /* si_connect */
|
||||
local_accept, /* si_accept */
|
||||
@ -303,6 +306,87 @@ static int local_bind(FAR struct socket *psock,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: local_getsockname
|
||||
*
|
||||
* Description:
|
||||
* The local_getsockname() function retrieves the locally-bound name of
|
||||
* the specified local socket, stores this address in the sockaddr
|
||||
* structure pointed to by the 'addr' argument, and stores the length of
|
||||
* this address in the object pointed to by the 'addrlen' argument.
|
||||
*
|
||||
* If the actual length of the address is greater than the length of the
|
||||
* supplied sockaddr structure, the stored address will be truncated.
|
||||
*
|
||||
* If the socket has not been bound to a local name, the value stored in
|
||||
* the object pointed to by address is unspecified.
|
||||
*
|
||||
* Parameters:
|
||||
* psock Socket structure of the socket to be queried
|
||||
* addr sockaddr structure to receive data [out]
|
||||
* addrlen Length of sockaddr structure [in/out]
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, 0 is returned, the 'addr' argument points to the address
|
||||
* of the socket, and the 'addrlen' argument points to the length of the
|
||||
* address. Otherwise, a negated errno value is returned. See
|
||||
* getsockname() for the list of appropriate error numbers.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int local_getsockname(FAR struct socket *psock,
|
||||
FAR struct sockaddr *addr,
|
||||
FAR socklen_t *addrlen)
|
||||
{
|
||||
FAR const struct sockaddr_un *unaddr =
|
||||
(FAR const struct sockaddr_un *)addr;
|
||||
FAR struct local_conn_s *conn;
|
||||
|
||||
DEBUGASSERT(psock != NULL && psock->s_conn != NULL &&
|
||||
unaddr != NULL && addrlen != NULL &&
|
||||
*addrlen >= sizeof(sa_family_t));
|
||||
|
||||
if (*addrlen < sizeof(sa_family_t))
|
||||
{
|
||||
/* This is apparently not an error */
|
||||
|
||||
*addrlen = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
conn = (FAR struct local_conn_s *)psock->s_conn;
|
||||
|
||||
/* Save the address family */
|
||||
|
||||
unaddr->sun_family = AF_LOCAL;
|
||||
if (*addrlen > sizeof(sa_family_t))
|
||||
{
|
||||
/* Now copy the address description. */
|
||||
|
||||
if (conn->lc_type == LOCAL_TYPE_UNNAMED)
|
||||
{
|
||||
/* Zero-length sun_path... This is an abstract Unix domain socket */
|
||||
|
||||
*addrlen = sizeof(sa_family_t);
|
||||
}
|
||||
else /* conn->lctype = LOCAL_TYPE_PATHNAME */
|
||||
{
|
||||
/* Get the available length in the user-provided buffer. */
|
||||
|
||||
int pathlen = *addrlen - sizeof(sa_family_t);
|
||||
|
||||
/* Copy the path into the user address structure */
|
||||
|
||||
(void)strncpy(unaddr->sun_path, conn->lc_path, pathlen);
|
||||
unaddr->sun_path[pathlen - 1] = '\0';
|
||||
|
||||
*addrlen = sizeof(sa_family_t) + namelen;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: local_connect
|
||||
*
|
||||
|
@ -63,6 +63,8 @@ static sockcaps_t pkt_sockcaps(FAR struct socket *psock);
|
||||
static void pkt_addref(FAR struct socket *psock);
|
||||
static int pkt_bind(FAR struct socket *psock,
|
||||
FAR const struct sockaddr *addr, socklen_t addrlen);
|
||||
static int pkt_getsockname(FAR struct socket *psock,
|
||||
FAR struct sockaddr *addr, FAR socklen_t *addrlen);
|
||||
static int pkt_listen(FAR struct socket *psock, int backlog);
|
||||
static int pkt_connect(FAR struct socket *psock,
|
||||
FAR const struct sockaddr *addr, socklen_t addrlen);
|
||||
@ -85,6 +87,7 @@ const struct sock_intf_s g_pkt_sockif =
|
||||
pkt_sockcaps, /* si_sockcaps */
|
||||
pkt_addref, /* si_addref */
|
||||
pkt_bind, /* si_bind */
|
||||
pkt_getsockname, /* si_getsockname */
|
||||
pkt_listen, /* si_listen */
|
||||
pkt_connect, /* si_connect */
|
||||
pkt_accept, /* si_accept */
|
||||
@ -378,6 +381,40 @@ static int pkt_bind(FAR struct socket *psock, FAR const struct sockaddr *addr,
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pkt_getsockname
|
||||
*
|
||||
* Description:
|
||||
* The pkt_getsockname() function retrieves the locally-bound name of the
|
||||
* specified packet socket, stores this address in the sockaddr structure
|
||||
* pointed to by the 'addr' argument, and stores the length of this
|
||||
* address in the object pointed to by the 'addrlen' argument.
|
||||
*
|
||||
* If the actual length of the address is greater than the length of the
|
||||
* supplied sockaddr structure, the stored address will be truncated.
|
||||
*
|
||||
* If the socket has not been bound to a local name, the value stored in
|
||||
* the object pointed to by address is unspecified.
|
||||
*
|
||||
* Parameters:
|
||||
* psock Socket structure of the socket to be queried
|
||||
* addr sockaddr structure to receive data [out]
|
||||
* addrlen Length of sockaddr structure [in/out]
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, 0 is returned, the 'addr' argument points to the address
|
||||
* of the socket, and the 'addrlen' argument points to the length of the
|
||||
* address. Otherwise, a negated errno value is returned. See
|
||||
* getsockname() for the list of appropriate error numbers.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int pkt_getsockname(FAR struct socket *psock,
|
||||
FAR struct sockaddr *addr, FAR socklen_t *addrlen)
|
||||
{
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pkt_listen
|
||||
*
|
||||
|
@ -49,6 +49,14 @@ else ifeq ($(CONFIG_NET_IPv6),y)
|
||||
SOCK_CSRCS += inet_sockif.c inet_recvfrom.c inet_connect.c inet_close.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NET_IPv4),y)
|
||||
SOCK_CSRCS += ipv4_getsockname.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_NET_IPv6),y)
|
||||
SOCK_CSRCS += ipv6_getsockname.c
|
||||
endif
|
||||
|
||||
# TCP/IP support
|
||||
|
||||
ifeq ($(CONFIG_NET_TCP),y)
|
||||
|
@ -47,308 +47,11 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
#include <nuttx/net/udp.h>
|
||||
|
||||
#include "utils/utils.h"
|
||||
#include "netdev/netdev.h"
|
||||
#include "tcp/tcp.h"
|
||||
#include "udp/udp.h"
|
||||
#include "socket/socket.h"
|
||||
#include "usrsock/usrsock.h"
|
||||
|
||||
#ifdef CONFIG_NET
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: get_ipv4_sockname
|
||||
*
|
||||
* Description:
|
||||
* The getsockname() function retrieves the locally-bound name of the
|
||||
* specified PF_NET socket.
|
||||
*
|
||||
* Parameters:
|
||||
* psock Point to the socket structure instance [in]
|
||||
* addr sockaddr structure to receive data [out]
|
||||
* addrlen Length of sockaddr structure [in/out]
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, 0 is returned, the 'addr' argument points to the address
|
||||
* of the socket, and the 'addrlen' argument points to the length of the
|
||||
* address. Otherwise, -1 is returned and errno is set to indicate the error.
|
||||
* Possible errno values that may be returned include:
|
||||
*
|
||||
* EBADF - The socket argument is not a valid file descriptor.
|
||||
* EOPNOTSUPP - The operation is not supported for this socket's protocol.
|
||||
* EINVAL - The socket has been shut down.
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
int ipv4_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
|
||||
FAR socklen_t *addrlen)
|
||||
{
|
||||
FAR struct net_driver_s *dev;
|
||||
#if defined(NET_TCP_HAVE_STACK) || defined(NET_UDP_HAVE_STACK)
|
||||
FAR struct sockaddr_in *outaddr = (FAR struct sockaddr_in *)addr;
|
||||
#endif
|
||||
#ifdef CONFIG_NETDEV_MULTINIC
|
||||
in_addr_t lipaddr;
|
||||
in_addr_t ripaddr;
|
||||
#endif
|
||||
|
||||
/* Check if enough space has been provided for the full address */
|
||||
|
||||
if (*addrlen < sizeof(struct sockaddr_in))
|
||||
{
|
||||
/* This function is supposed to return the partial address if
|
||||
* a smaller buffer has been provided. This support has not
|
||||
* been implemented.
|
||||
*/
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/* Set the port number */
|
||||
|
||||
switch (psock->s_type)
|
||||
{
|
||||
#ifdef NET_TCP_HAVE_STACK
|
||||
case SOCK_STREAM:
|
||||
{
|
||||
FAR struct tcp_conn_s *tcp_conn = (FAR struct tcp_conn_s *)psock->s_conn;
|
||||
outaddr->sin_port = tcp_conn->lport; /* Already in network byte order */
|
||||
#ifdef CONFIG_NETDEV_MULTINIC
|
||||
lipaddr = tcp_conn->u.ipv4.laddr;
|
||||
ripaddr = tcp_conn->u.ipv4.raddr;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef NET_UDP_HAVE_STACK
|
||||
case SOCK_DGRAM:
|
||||
{
|
||||
FAR struct udp_conn_s *udp_conn = (FAR struct udp_conn_s *)psock->s_conn;
|
||||
outaddr->sin_port = udp_conn->lport; /* Already in network byte order */
|
||||
#ifdef CONFIG_NETDEV_MULTINIC
|
||||
lipaddr = udp_conn->u.ipv4.laddr;
|
||||
ripaddr = udp_conn->u.ipv4.raddr;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETDEV_MULTINIC
|
||||
/* The socket/connection does not know its IP address unless
|
||||
* CONFIG_NETDEV_MULTINIC is selected. Otherwise the design supports only
|
||||
* a single network device and only the network device knows the IP address.
|
||||
*/
|
||||
|
||||
if (lipaddr == 0)
|
||||
{
|
||||
#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_UDP)
|
||||
outaddr->sin_family = AF_INET;
|
||||
outaddr->sin_addr.s_addr = 0;
|
||||
*addrlen = sizeof(struct sockaddr_in);
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
net_lock();
|
||||
|
||||
#ifdef CONFIG_NETDEV_MULTINIC
|
||||
/* Find the device matching the IPv4 address in the connection structure.
|
||||
* NOTE: listening sockets have no ripaddr. Work around is to use the
|
||||
* lipaddr when ripaddr is not available.
|
||||
*/
|
||||
|
||||
if (ripaddr == 0)
|
||||
{
|
||||
ripaddr = lipaddr;
|
||||
}
|
||||
|
||||
dev = netdev_findby_ipv4addr(lipaddr, ripaddr);
|
||||
#else
|
||||
/* There is only one, the first network device in the list. */
|
||||
|
||||
dev = g_netdevices;
|
||||
#endif
|
||||
|
||||
if (!dev)
|
||||
{
|
||||
net_unlock();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Set the address family and the IP address */
|
||||
|
||||
#if defined(NET_TCP_HAVE_STACK) || defined(NET_UDP_HAVE_STACK)
|
||||
outaddr->sin_family = AF_INET;
|
||||
outaddr->sin_addr.s_addr = dev->d_ipaddr;
|
||||
*addrlen = sizeof(struct sockaddr_in);
|
||||
#endif
|
||||
net_unlock();
|
||||
|
||||
/* Return success */
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ipv6_getsockname
|
||||
*
|
||||
* Description:
|
||||
* The getsockname() function retrieves the locally-bound name of the
|
||||
* specified PF_NET6 socket.
|
||||
*
|
||||
* Parameters:
|
||||
* psock Point to the socket structure instance [in]
|
||||
* addr sockaddr structure to receive data [out]
|
||||
* addrlen Length of sockaddr structure [in/out]
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, 0 is returned, the 'addr' argument points to the address
|
||||
* of the socket, and the 'addrlen' argument points to the length of the
|
||||
* address. Otherwise, -1 is returned and errno is set to indicate the error.
|
||||
* Possible errno values that may be returned include:
|
||||
*
|
||||
* EBADF - The socket argument is not a valid file descriptor.
|
||||
* EOPNOTSUPP - The operation is not supported for this socket's protocol.
|
||||
* EINVAL - The socket has been shut down.
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
int ipv6_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
|
||||
FAR socklen_t *addrlen)
|
||||
{
|
||||
FAR struct net_driver_s *dev;
|
||||
#if defined(NET_TCP_HAVE_STACK) || defined(NET_UDP_HAVE_STACK)
|
||||
FAR struct sockaddr_in6 *outaddr = (FAR struct sockaddr_in6 *)addr;
|
||||
#endif
|
||||
#ifdef CONFIG_NETDEV_MULTINIC
|
||||
net_ipv6addr_t *lipaddr;
|
||||
net_ipv6addr_t *ripaddr;
|
||||
#endif
|
||||
|
||||
/* Check if enough space has been provided for the full address */
|
||||
|
||||
if (*addrlen < sizeof(struct sockaddr_in6))
|
||||
{
|
||||
/* This function is supposed to return the partial address if
|
||||
* a smaller buffer has been provided. This support has not
|
||||
* been implemented.
|
||||
*/
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/* Set the port number */
|
||||
|
||||
switch (psock->s_type)
|
||||
{
|
||||
#ifdef NET_TCP_HAVE_STACK
|
||||
case SOCK_STREAM:
|
||||
{
|
||||
FAR struct tcp_conn_s *tcp_conn = (FAR struct tcp_conn_s *)psock->s_conn;
|
||||
outaddr->sin6_port = tcp_conn->lport; /* Already in network byte order */
|
||||
#ifdef CONFIG_NETDEV_MULTINIC
|
||||
lipaddr = &tcp_conn->u.ipv6.laddr;
|
||||
ripaddr = &tcp_conn->u.ipv6.raddr;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef NET_UDP_HAVE_STACK
|
||||
case SOCK_DGRAM:
|
||||
{
|
||||
FAR struct udp_conn_s *udp_conn = (FAR struct udp_conn_s *)psock->s_conn;
|
||||
outaddr->sin6_port = udp_conn->lport; /* Already in network byte order */
|
||||
#ifdef CONFIG_NETDEV_MULTINIC
|
||||
lipaddr = &udp_conn->u.ipv6.laddr;
|
||||
ripaddr = &udp_conn->u.ipv6.raddr;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NETDEV_MULTINIC
|
||||
/* The socket/connection does not know its IP address unless
|
||||
* CONFIG_NETDEV_MULTINIC is selected. Otherwise the design supports only
|
||||
* a single network device and only the network device knows the IP address.
|
||||
*/
|
||||
|
||||
if (net_ipv6addr_cmp(lipaddr, g_ipv6_allzeroaddr))
|
||||
{
|
||||
#if defined(NET_TCP_HAVE_STACK) || defined(NET_UDP_HAVE_STACK)
|
||||
outaddr->sin6_family = AF_INET6;
|
||||
memcpy(outaddr->sin6_addr.in6_u.u6_addr8, g_ipv6_allzeroaddr, 16);
|
||||
*addrlen = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
net_lock();
|
||||
|
||||
#ifdef CONFIG_NETDEV_MULTINIC
|
||||
/* Find the device matching the IPv6 address in the connection structure.
|
||||
* NOTE: listening sockets have no ripaddr. Work around is to use the
|
||||
* lipaddr when ripaddr is not available.
|
||||
*/
|
||||
|
||||
if (net_ipv6addr_cmp(ripaddr, g_ipv6_allzeroaddr))
|
||||
{
|
||||
ripaddr = lipaddr;
|
||||
}
|
||||
|
||||
dev = netdev_findby_ipv6addr(*lipaddr, *ripaddr);
|
||||
#else
|
||||
/* There is only one, the first network device in the list. */
|
||||
|
||||
dev = g_netdevices;
|
||||
#endif
|
||||
|
||||
if (!dev)
|
||||
{
|
||||
net_unlock();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Set the address family and the IP address */
|
||||
|
||||
#if defined(NET_TCP_HAVE_STACK) || defined(NET_UDP_HAVE_STACK)
|
||||
outaddr->sin6_family = AF_INET6;
|
||||
memcpy(outaddr->sin6_addr.in6_u.u6_addr8, dev->d_ipv6addr, 16);
|
||||
*addrlen = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
net_unlock();
|
||||
|
||||
/* Return success */
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -380,10 +83,11 @@ int ipv6_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
|
||||
* Possible errno values that may be returned include:
|
||||
*
|
||||
* EBADF - The socket argument is not a valid file descriptor.
|
||||
* ENOTSOCK - The socket argument does not refer to a socket.
|
||||
* EOPNOTSUPP - The operation is not supported for this socket's protocol.
|
||||
* EINVAL - The socket has been shut down.
|
||||
*
|
||||
* Assumptions:
|
||||
* ENOBUFS - Insufficient resources were available in the system to
|
||||
* complete the function.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@ -395,7 +99,7 @@ int getsockname(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
|
||||
|
||||
/* Verify that the sockfd corresponds to valid, allocated socket */
|
||||
|
||||
if (!psock || psock->s_crefs <= 0)
|
||||
if (psock == NULL || psock->s_crefs <= 0)
|
||||
{
|
||||
errcode = EBADF;
|
||||
goto errout;
|
||||
@ -406,54 +110,19 @@ int getsockname(int sockfd, FAR struct sockaddr *addr, FAR socklen_t *addrlen)
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
if (!addr || !addrlen)
|
||||
if (addr == NULL || addrlen <= 0)
|
||||
{
|
||||
errcode = EINVAL;
|
||||
goto errout;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_USRSOCK
|
||||
if (psock->s_type == SOCK_USRSOCK_TYPE)
|
||||
{
|
||||
FAR struct usrsock_conn_s *conn = psock->s_conn;
|
||||
/* Let the address family's send() method handle the operation */
|
||||
|
||||
DEBUGASSERT(conn);
|
||||
DEBUGASSERT(psock->s_sockif != NULL &&
|
||||
psock->s_sockif->si_getsockname != NULL);
|
||||
|
||||
/* Handle usrsock getsockname */
|
||||
|
||||
ret = usrsock_getsockname(conn, addr, addrlen);
|
||||
if (ret < 0)
|
||||
{
|
||||
errcode = -ret;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Handle by address domain */
|
||||
|
||||
switch (psock->s_domain)
|
||||
{
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
case PF_INET:
|
||||
ret = ipv4_getsockname(psock, addr, addrlen);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
case PF_INET6:
|
||||
ret = ipv6_getsockname(psock, addr, addrlen);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case PF_PACKET:
|
||||
default:
|
||||
errcode = EAFNOSUPPORT;
|
||||
goto errout;
|
||||
}
|
||||
ret = psock->s_sockif->si_getsockname(psock, addr, addrlen);
|
||||
|
||||
/* Check for failure */
|
||||
|
||||
|
@ -63,6 +63,8 @@ static sockcaps_t inet_sockcaps(FAR struct socket *psock);
|
||||
static void inet_addref(FAR struct socket *psock);
|
||||
static int inet_bind(FAR struct socket *psock,
|
||||
FAR const struct sockaddr *addr, socklen_t addrlen);
|
||||
static int inet_getsockname(FAR struct socket *psock,
|
||||
FAR struct sockaddr *addr, FAR socklen_t *addrlen);
|
||||
static int inet_listen(FAR struct socket *psock, int backlog);
|
||||
static int inet_accept(FAR struct socket *psock,
|
||||
FAR struct sockaddr *addr, FAR socklen_t *addrlen,
|
||||
@ -83,6 +85,7 @@ const struct sock_intf_s g_inet_sockif =
|
||||
inet_sockcaps, /* si_sockcaps */
|
||||
inet_addref, /* si_addref */
|
||||
inet_bind, /* si_bind */
|
||||
inet_getsockname, /* si_getsockname */
|
||||
inet_listen, /* si_listen */
|
||||
inet_connect, /* si_connect */
|
||||
inet_accept, /* si_accept */
|
||||
@ -544,6 +547,72 @@ static int inet_bind(FAR struct socket *psock,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: inet_getsockname
|
||||
*
|
||||
* Description:
|
||||
* The inet_getsockname() function retrieves the locally-bound name of
|
||||
* the specified INET socket, stores this address in the sockaddr
|
||||
* structure pointed to by the 'addr' argument, and stores the length of
|
||||
* this address in the object pointed to by the 'addrlen' argument.
|
||||
*
|
||||
* If the actual length of the address is greater than the length of the
|
||||
* supplied sockaddr structure, the stored address will be truncated.
|
||||
*
|
||||
* If the socket has not been bound to a local name, the value stored in
|
||||
* the object pointed to by address is unspecified.
|
||||
*
|
||||
* Parameters:
|
||||
* psock Socket structure of the socket to be queried
|
||||
* addr sockaddr structure to receive data [out]
|
||||
* addrlen Length of sockaddr structure [in/out]
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, 0 is returned, the 'addr' argument points to the address
|
||||
* of the socket, and the 'addrlen' argument points to the length of the
|
||||
* address. Otherwise, a negated errno value is returned. See
|
||||
* getsockname() for the list of appropriate error numbers.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int inet_getsockname(FAR struct socket *psock,
|
||||
FAR struct sockaddr *addr,
|
||||
FAR socklen_t *addrlen)
|
||||
{
|
||||
#ifdef CONFIG_NET_USRSOCK
|
||||
if (psock->s_type == SOCK_USRSOCK_TYPE)
|
||||
{
|
||||
FAR struct usrsock_conn_s *conn = psock->s_conn;
|
||||
|
||||
DEBUGASSERT(conn != NULL);
|
||||
|
||||
/* Handle usrsock getsockname */
|
||||
|
||||
return usrsock_getsockname(conn, addr, addrlen);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Handle by address domain */
|
||||
|
||||
switch (psock->s_domain)
|
||||
{
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
case PF_INET:
|
||||
return ipv4_getsockname(psock, addr, addrlen);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
case PF_INET6:
|
||||
return ipv6_getsockname(psock, addr, addrlen);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: inet_listen
|
||||
*
|
||||
|
@ -436,6 +436,35 @@ int net_timeo(systime_t start_time, socktimeo_t timeo);
|
||||
ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len,
|
||||
int flags);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ipv4_getsockname and ipv6_sockname
|
||||
*
|
||||
* Description:
|
||||
* The ipv4_getsockname() and ipv6_getsocknam() function retrieve the
|
||||
* locally-bound name of the specified INET socket.
|
||||
*
|
||||
* Parameters:
|
||||
* psock Point to the socket structure instance [in]
|
||||
* addr sockaddr structure to receive data [out]
|
||||
* addrlen Length of sockaddr structure [in/out]
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, 0 is returned, the 'addr' argument points to the address
|
||||
* of the socket, and the 'addrlen' argument points to the length of the
|
||||
* address. Otherwise, a negated errno value is returned. See
|
||||
* getsockname() for the list of returned error values.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
int ipv4_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
|
||||
FAR socklen_t *addrlen);
|
||||
#endif
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
int ipv6_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
|
||||
FAR socklen_t *addrlen);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: inet_connect
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user