This is an automated email from the ASF dual-hosted git repository. casaroli pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 735a89c97e7b91cdd8353e6a095fa5f627dbf8c3 Author: wangjinjing1 <[email protected]> AuthorDate: Thu May 14 22:15:14 2026 +0800 net/can: implement getsockname for CAN sockets Add can_getsockname() to return the locally-bound CAN interface index via getsockname() syscall, matching Linux raw_getname() behavior. When CONFIG_NETDEV_IFINDEX is enabled, returns d_ifindex directly; otherwise extracts index from device name "can<N>" to mirror the bind logic. A buffer smaller than struct sockaddr_can is rejected with EINVAL, as in ipv4_getsockname(), and the behavior is documented in socketcan.rst. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: wangjinjing1 <[email protected]> Signed-off-by: p-szafonimateusz <[email protected]> --- Documentation/os/networking/socketcan.rst | 9 ++++ net/can/can_sockif.c | 74 ++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/Documentation/os/networking/socketcan.rst b/Documentation/os/networking/socketcan.rst index 8db7955979a..8e4136ad266 100644 --- a/Documentation/os/networking/socketcan.rst +++ b/Documentation/os/networking/socketcan.rst @@ -155,6 +155,15 @@ If the network device is not a loopback device, the stack loops the frame back itself after the driver accepted it. Looped back frames are counted in the received CAN statistics. +Socket Address +-------------- + +``getsockname()`` returns a ``struct sockaddr_can`` with ``can_family`` set +to ``AF_CAN`` and ``can_ifindex`` set to the index of the interface the +socket is bound to, or 0 if the socket is not bound to an interface. The +address buffer must be at least ``sizeof(struct sockaddr_can)`` bytes, +otherwise ``EINVAL`` is returned. + Features -------- diff --git a/net/can/can_sockif.c b/net/can/can_sockif.c index 32cffb8f741..585dcfcf665 100644 --- a/net/can/can_sockif.c +++ b/net/can/can_sockif.c @@ -57,6 +57,9 @@ static sockcaps_t can_sockcaps(FAR struct socket *psock); static void can_addref(FAR struct socket *psock); static int can_bind(FAR struct socket *psock, FAR const struct sockaddr *addr, socklen_t addrlen); +static int can_getsockname(FAR struct socket *psock, + FAR struct sockaddr *addr, + FAR socklen_t *addrlen); static int can_poll_local(FAR struct socket *psock, FAR struct pollfd_s *fds, bool setup); static int can_close(FAR struct socket *psock); @@ -71,7 +74,7 @@ const struct sock_intf_s g_can_sockif = can_sockcaps, /* si_sockcaps */ can_addref, /* si_addref */ can_bind, /* si_bind */ - NULL, /* si_getsockname */ + can_getsockname, /* si_getsockname */ NULL, /* si_getpeername */ NULL, /* si_listen */ NULL, /* si_connect */ @@ -354,6 +357,75 @@ static int can_bind(FAR struct socket *psock, return conn->dev == NULL && canaddr->can_ifindex != 0 ? -ENODEV : OK; } +/**************************************************************************** + * Name: can_getsockname + * + * Description: + * The can_getsockname() function retrieves the locally-bound name of the + * specified CAN 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. + * + * Input 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. Otherwise, a negated errno value is + * returned. + * + ****************************************************************************/ + +static int can_getsockname(FAR struct socket *psock, + FAR struct sockaddr *addr, + FAR socklen_t *addrlen) +{ + FAR struct sockaddr_can *canaddr; + FAR struct can_conn_s *conn; + + /* Check if enough space has been provided for the full address */ + + if (*addrlen < sizeof(struct sockaddr_can)) + { + /* This function is supposed to return the partial address if + * a smaller buffer has been provided. This support has not + * been implemented. + */ + + return -EINVAL; + } + + conn = psock->s_conn; + + /* Return the address information in the address structure */ + + canaddr = (FAR struct sockaddr_can *)addr; + memset(canaddr, 0, sizeof(struct sockaddr_can)); + + canaddr->can_family = AF_CAN; + + if (conn->dev != NULL) + { +#ifdef CONFIG_NETDEV_IFINDEX + canaddr->can_ifindex = conn->dev->d_ifindex; +#else + /* Reverse mapping: extract ifindex from device name "can<N>". + * This mirrors the bind logic which maps ifindex -> "can<N>". + */ + + canaddr->can_ifindex = conn->dev->d_ifname[3] - '0'; +#endif + } + else + { + canaddr->can_ifindex = 0; + } + + *addrlen = sizeof(struct sockaddr_can); + return OK; +} + /**************************************************************************** * Name: can_poll_local *
