Skip to content

Commit

Permalink
net/ and include/nuttx/net: Add getpeername() support
Browse files Browse the repository at this point in the history
  • Loading branch information
GUIDINGLI authored and gregory-nutt committed Jul 19, 2018
1 parent a1cddfb commit e840038
Show file tree
Hide file tree
Showing 13 changed files with 410 additions and 4 deletions.
40 changes: 40 additions & 0 deletions include/nuttx/net/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
*
Expand Down
2 changes: 2 additions & 0 deletions include/sys/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
63 changes: 63 additions & 0 deletions net/bluetooth/bluetooth_sockif.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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
*
Expand Down
37 changes: 37 additions & 0 deletions net/icmp/icmp_sockif.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 */
Expand Down Expand Up @@ -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
*
Expand Down
37 changes: 37 additions & 0 deletions net/icmpv6/icmpv6_sockif.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 */
Expand Down Expand Up @@ -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
*
Expand Down
65 changes: 65 additions & 0 deletions net/ieee802154/ieee802154_sockif.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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
*
Expand Down
4 changes: 2 additions & 2 deletions net/inet/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
29 changes: 29 additions & 0 deletions net/inet/inet.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
Loading

0 comments on commit e840038

Please sign in to comment.