net/ and include/nuttx/net: Add getpeername() support

This commit is contained in:
ligd 2018-07-19 07:16:30 -06:00 committed by Gregory Nutt
parent a1cddfbc8c
commit e840038f2d
13 changed files with 410 additions and 4 deletions

View File

@ -155,6 +155,8 @@ struct sock_intf_s
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_getpeername)(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);
@ -1068,6 +1070,44 @@ int psock_getsockopt(FAR struct socket *psock, int level, int option,
int psock_setsockopt(FAR struct socket *psock, int level, int option,
FAR const void *value, socklen_t value_len);
/****************************************************************************
* Name: psock_getpeername
*
* Description:
* The psock_getpeername() function retrieves the remote-connected name of
* the specified 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 socket to operate on
* 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.
* 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.
* ENOBUFS - Insufficient resources were available in the system to
* complete the function.
*
****************************************************************************/
int psock_getpeername(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen);
/****************************************************************************
* Name: psock_ioctl
*

View File

@ -298,6 +298,8 @@ int getsockopt(int sockfd, int level, int option,
int getsockname(int sockfd, FAR struct sockaddr *addr,
FAR socklen_t *addrlen);
int getpeername(int sockfd, FAR struct sockaddr *addr,
FAR socklen_t *addrlen);
#undef EXTERN
#if defined(__cplusplus)

View File

@ -98,6 +98,7 @@ const struct sock_intf_s g_bluetooth_sockif =
bluetooth_addref, /* si_addref */
bluetooth_bind, /* si_bind */
bluetooth_getsockname, /* si_getsockname */
bluetooth_getpeername, /* si_getpeername */
bluetooth_listen, /* si_listen */
bluetooth_connect, /* si_connect */
bluetooth_accept, /* si_accept */
@ -505,6 +506,68 @@ static int bluetooth_getsockname(FAR struct socket *psock,
return OK;
}
/****************************************************************************
* Name: bluetooth_getpeername
*
* Description:
* The bluetooth_getpeername() function retrieves the remote-connected 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
* getpeername() for the list of appropriate error numbers.
*
****************************************************************************/
static int bluetooth_getpeername(FAR struct socket *psock,
FAR struct sockaddr *addr,
FAR socklen_t *addrlen)
{
FAR struct bluetooth_conn_s *conn;
FAR struct sockaddr_bt_s tmp;
socklen_t copylen;
DEBUGASSERT(psock != NULL && addr != NULL && addrlen != NULL);
conn = (FAR struct bluetooth_conn_s *)psock->s_conn;
DEBUGASSERT(conn != NULL);
/* Create a copy of the full address on the stack */
tmp.bt_family = AF_BLUETOOTH;
memcpy(&tmp.bt_bdaddr, &conn->bc_raddr, sizeof(bt_addr_t));
/* Copy to the user buffer, truncating if necessary */
copylen = sizeof(struct sockaddr_bt_s);
if (copylen > *addrlen)
{
copylen = *addrlen;
}
memcpy(addr, &tmp, copylen);
/* Return the actual size transferred */
*addrlen = copylen;
return OK;
}
/****************************************************************************
* Name: bluetooth_listen
*

View File

@ -66,6 +66,8 @@ static int icmp_bind(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
static int icmp_getsockname(FAR struct socket *psock,
FAR struct sockaddr *addr, FAR socklen_t *addrlen);
static int icmp_getpeername(FAR struct socket *psock,
FAR struct sockaddr *addr, FAR socklen_t *addrlen);
static int icmp_listen(FAR struct socket *psock, int backlog);
static int icmp_connect(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
@ -91,6 +93,7 @@ const struct sock_intf_s g_icmp_sockif =
icmp_addref, /* si_addref */
icmp_bind, /* si_bind */
icmp_getsockname, /* si_getsockname */
icmp_getpeername, /* si_getpeername */
icmp_listen, /* si_listen */
icmp_connect, /* si_connect */
icmp_accept, /* si_accept */
@ -361,6 +364,40 @@ static int icmp_getsockname(FAR struct socket *psock,
return -EAFNOSUPPORT;
}
/****************************************************************************
* Name: icmp_getpeername
*
* Description:
* The icmp_getpeername() function retrieves the remote-connected 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
* getpeername() for the list of appropriate error numbers.
*
****************************************************************************/
static int icmp_getpeername(FAR struct socket *psock,
FAR struct sockaddr *addr, FAR socklen_t *addrlen)
{
return -EAFNOSUPPORT;
}
/****************************************************************************
* Name: icmp_listen
*

View File

@ -66,6 +66,8 @@ static int icmpv6_bind(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
static int icmpv6_getsockname(FAR struct socket *psock,
FAR struct sockaddr *addr, FAR socklen_t *addrlen);
static int icmpv6_getpeername(FAR struct socket *psock,
FAR struct sockaddr *addr, FAR socklen_t *addrlen);
static int icmpv6_listen(FAR struct socket *psock, int backlog);
static int icmpv6_connect(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
@ -91,6 +93,7 @@ const struct sock_intf_s g_icmpv6_sockif =
icmpv6_addref, /* si_addref */
icmpv6_bind, /* si_bind */
icmpv6_getsockname, /* si_getsockname */
icmpv6_getpeername, /* si_getpeername */
icmpv6_listen, /* si_listen */
icmpv6_connect, /* si_connect */
icmpv6_accept, /* si_accept */
@ -361,6 +364,40 @@ static int icmpv6_getsockname(FAR struct socket *psock,
return -EAFNOSUPPORT;
}
/****************************************************************************
* Name: icmpv6_getpeername
*
* Description:
* The icmpv6_getpeername() function retrieves the remote-connected 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
* getpeername() for the list of appropriate error numbers.
*
****************************************************************************/
static int icmpv6_getpeername(FAR struct socket *psock,
FAR struct sockaddr *addr, FAR socklen_t *addrlen)
{
return -EAFNOSUPPORT;
}
/****************************************************************************
* Name: icmpv6_listen
*

View File

@ -68,6 +68,8 @@ static int ieee802154_bind(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
static int ieee802154_getsockname(FAR struct socket *psock,
FAR struct sockaddr *addr, FAR socklen_t *addrlen);
static int ieee802154_getpeername(FAR struct socket *psock,
FAR struct sockaddr *addr, FAR socklen_t *addrlen);
static int ieee802154_listen(FAR struct socket *psock, int backlog);
static int ieee802154_connect(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
@ -96,6 +98,7 @@ const struct sock_intf_s g_ieee802154_sockif =
ieee802154_addref, /* si_addref */
ieee802154_bind, /* si_bind */
ieee802154_getsockname, /* si_getsockname */
ieee802154_getpeername, /* si_getpeername */
ieee802154_listen, /* si_listen */
ieee802154_connect, /* si_connect */
ieee802154_accept, /* si_accept */
@ -512,6 +515,68 @@ static int ieee802154_getsockname(FAR struct socket *psock,
return OK;
}
/****************************************************************************
* Name: ieee802154_getpeername
*
* Description:
* The ieee802154_getpeername() function retrieves the remote-connectd 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
* getpeername() for the list of appropriate error numbers.
*
****************************************************************************/
static int ieee802154_getpeername(FAR struct socket *psock,
FAR struct sockaddr *addr, FAR
socklen_t *addrlen)
{
FAR struct ieee802154_conn_s *conn;
FAR struct sockaddr_ieee802154_s tmp;
socklen_t copylen;
DEBUGASSERT(psock != NULL && addr != NULL && addrlen != NULL);
conn = (FAR struct ieee802154_conn_s *)psock->s_conn;
DEBUGASSERT(conn != NULL);
/* Create a copy of the full address on the stack */
tmp.sa_family = PF_IEEE802154;
memcpy(&tmp.sa_addr, &conn->raddr, sizeof(struct ieee802154_saddr_s));
/* Copy to the user buffer, truncating if necessary */
copylen = sizeof(struct sockaddr_ieee802154_s);
if (copylen > *addrlen)
{
copylen = *addrlen;
}
memcpy(addr, &tmp, copylen);
/* Return the actual size transferred */
*addrlen = copylen;
return OK;
}
/****************************************************************************
* Name: ieee802154_listen
*

View File

@ -44,11 +44,11 @@ SOCK_CSRCS += inet_globals.c
endif
ifeq ($(CONFIG_NET_IPv4),y)
SOCK_CSRCS += ipv4_getsockname.c inet_setipid.c
SOCK_CSRCS += ipv4_getsockname.c ipv4_getpeername.c inet_setipid.c
endif
ifeq ($(CONFIG_NET_IPv6),y)
SOCK_CSRCS += ipv6_getsockname.c
SOCK_CSRCS += ipv6_getsockname.c ipv6_getpeername.c
endif
# Include inet build support

View File

@ -171,6 +171,35 @@ int ipv6_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen);
#endif
/****************************************************************************
* Name: ipv4_getpeername and ipv6_peername
*
* Description:
* The ipv4_getpeername() and ipv6_getsocknam() function retrieve the
* remote-connected 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
* getpeername() for the list of returned error values.
*
****************************************************************************/
#ifdef CONFIG_NET_IPv4
int ipv4_getpeername(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen);
#endif
#ifdef CONFIG_NET_IPv6
int ipv6_getpeername(FAR struct socket *psock, FAR struct sockaddr *addr,
FAR socklen_t *addrlen);
#endif
/****************************************************************************
* Name: inet_recvfrom
*

View File

@ -69,6 +69,8 @@ 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_getpeername(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_connect(FAR struct socket *psock,
FAR const struct sockaddr *addr, socklen_t addrlen);
@ -100,6 +102,7 @@ static const struct sock_intf_s g_inet_sockif =
inet_addref, /* si_addref */
inet_bind, /* si_bind */
inet_getsockname, /* si_getsockname */
inet_getpeername, /* si_getpeername */
inet_listen, /* si_listen */
inet_connect, /* si_connect */
inet_accept, /* si_accept */
@ -520,6 +523,59 @@ static int inet_getsockname(FAR struct socket *psock,
}
}
/****************************************************************************
* Name: inet_getpeername
*
* Description:
* The inet_getpeername() function retrieves the remote-connected 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
* getpeername() for the list of appropriate error numbers.
*
****************************************************************************/
static int inet_getpeername(FAR struct socket *psock,
FAR struct sockaddr *addr,
FAR socklen_t *addrlen)
{
/* Handle by address domain */
switch (psock->s_domain)
{
#ifdef CONFIG_NET_IPv4
case PF_INET:
return ipv4_getpeername(psock, addr, addrlen);
break;
#endif
#ifdef CONFIG_NET_IPv6
case PF_INET6:
return ipv6_getpeername(psock, addr, addrlen);
break;
#endif
default:
return -EAFNOSUPPORT;
}
}
/****************************************************************************
* Name: inet_listen
*

View File

@ -67,6 +67,8 @@ 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_getpeername(FAR struct socket *psock,
FAR struct sockaddr *addr, FAR socklen_t *addrlen);
#ifndef CONFIG_NET_LOCAL_STREAM
static int local_listen(FAR struct socket *psock, int backlog);
#endif
@ -99,6 +101,7 @@ const struct sock_intf_s g_local_sockif =
local_addref, /* si_addref */
local_bind, /* si_bind */
local_getsockname, /* si_getsockname */
local_getpeername, /* si_getpeername */
local_listen, /* si_listen */
local_connect, /* si_connect */
local_accept, /* si_accept */
@ -420,6 +423,41 @@ static int local_getsockname(FAR struct socket *psock,
return OK;
}
/****************************************************************************
* Name: local_getpeername
*
* Description:
* The local_getpeername() function retrieves the remote-connected 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
* getpeername() for the list of appropriate error numbers.
*
****************************************************************************/
static int local_getpeername(FAR struct socket *psock,
FAR struct sockaddr *addr,
FAR socklen_t *addrlen)
{
return local_getsockname(psock, addr, addrlen);
}
/****************************************************************************
* Name: local_listen
*

View File

@ -69,6 +69,8 @@ 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_getpeername(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);
@ -96,6 +98,7 @@ const struct sock_intf_s g_pkt_sockif =
pkt_addref, /* si_addref */
pkt_bind, /* si_bind */
pkt_getsockname, /* si_getsockname */
pkt_getpeername, /* si_getpeername */
pkt_listen, /* si_listen */
pkt_connect, /* si_connect */
pkt_accept, /* si_accept */
@ -432,6 +435,40 @@ static int pkt_getsockname(FAR struct socket *psock,
return -EAFNOSUPPORT;
}
/****************************************************************************
* Name: pkt_getpeername
*
* Description:
* The pkt_getpeername() function retrieves the remote-connected 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
* getpeername() for the list of appropriate error numbers.
*
****************************************************************************/
static int pkt_getpeername(FAR struct socket *psock,
FAR struct sockaddr *addr, FAR socklen_t *addrlen)
{
return -EAFNOSUPPORT;
}
/****************************************************************************
* Name: pkt_listen
*

View File

@ -35,8 +35,9 @@
# Include socket source files
SOCK_CSRCS += bind.c connect.c getsockname.c recv.c recvfrom.c send.c
SOCK_CSRCS += sendto.c socket.c net_sockets.c net_close.c net_dupsd.c
SOCK_CSRCS += bind.c connect.c getsockname.c getpeername.c
SOCK_CSRCS += recv.c recvfrom.c send.c sendto.c
SOCK_CSRCS += socket.c net_sockets.c net_close.c net_dupsd.c
SOCK_CSRCS += net_dupsd2.c net_sockif.c net_clone.c net_poll.c net_vfcntl.c
SOCK_CSRCS += net_fstat.c

View File

@ -80,6 +80,7 @@ const struct sock_intf_s g_usrsock_sockif =
usrsock_sockif_addref, /* si_addref */
usrsock_bind, /* si_bind */
usrsock_getsockname, /* si_getsockname */
NULL, /* si_getpeername */
usrsock_sockif_listen, /* si_listen */
usrsock_connect, /* si_connect */
usrsock_sockif_accept, /* si_accept */