pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/35179?usp=email )
Change subject: socket: Introduce API osmo_sock_multiaddr_get_ip_and_port() ...................................................................... socket: Introduce API osmo_sock_multiaddr_get_ip_and_port() Related: SYS#6636 Related: OS#5581 Change-Id: I19d560ab4aadec18a4c0f94115675ec1d7ab14d7 --- M TODO-RELEASE M include/osmocom/core/socket.h M src/core/libosmocore.map M src/core/socket.c 4 files changed, 94 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/79/35179/1 diff --git a/TODO-RELEASE b/TODO-RELEASE index fa7bc57..e365746 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -8,6 +8,7 @@ # If any interfaces have been removed or changed since the last public release: c:r:0. #library what description / commit summary line core ADD osmo_sock_multiaddr_{add,del}_local_addr() +core ADD osmo_sock_multiaddr_get_ip_and_port() core ADD gsmtap_inst_fd2() core, DEPRECATE gsmtap_inst_fd() isdn ABI change add states and flags for external T200 handling gsm ABI change add T200 timer states to lapdm_datalink diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h index 03f1d39..9397343 100644 --- a/include/osmocom/core/socket.h +++ b/include/osmocom/core/socket.h @@ -191,6 +191,8 @@ int osmo_sock_get_remote_ip(int fd, char *host, size_t len); int osmo_sock_get_remote_ip_port(int fd, char *port, size_t len); +int osmo_sock_multiaddr_get_ip_and_port(int fd, int ip_proto, char *ip, size_t ip_len, size_t *ip_cnt, + char *port, size_t port_len, bool local); int osmo_sock_multiaddr_add_local_addr(int sfd, const char **addrs, size_t addrs_cnt); int osmo_sock_multiaddr_del_local_addr(int sfd, const char **addrs, size_t addrs_cnt); diff --git a/src/core/libosmocore.map b/src/core/libosmocore.map index 3d6aa42..1d00fe8 100644 --- a/src/core/libosmocore.map +++ b/src/core/libosmocore.map @@ -436,6 +436,7 @@ osmo_sock_mcast_ttl_set; osmo_sock_multiaddr_add_local_addr; osmo_sock_multiaddr_del_local_addr; +osmo_sock_multiaddr_get_ip_and_port; osmo_sock_set_dscp; osmo_sock_set_priority; osmo_sock_unix_init; diff --git a/src/core/socket.c b/src/core/socket.c index 1dc8e46..1d97018 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -1807,6 +1807,85 @@ return 0; } +/*! Get the IP and/or port number on socket in separate string buffers. + * \param[in] fd file descriptor of socket +* \param[out] ip_proto IPPROTO of the socket, eg: IPPROTO_SCTP. + * \param[out] ip Pointer to memory holding consecutive buffers of size ip_len + * \param[in] ip_len length of each of the string buffer in the the ip array + * \param[in] ip_cnt length ip array pointer. on return it contains the number of addresses found. + * \param[out] port number (will be filled in when not NULL) + * \param[in] port_len length of the port buffer + * \param[in] local (true) or remote (false) name will get looked at + * \returns 0 on success; negative otherwise + * + * Upon return, ip_cnt can be set to a higher value than the one set by the + * caller. This can be used by the caller to find out the required array length + * and then obtaining by calling the function twice. Only up to ip_cnt addresses + * are filed in, as per the value provided by the caller. + */ +int osmo_sock_multiaddr_get_ip_and_port(int fd, int ip_proto, char *ip, size_t ip_len, size_t *ip_cnt, + char *port, size_t port_len, bool local) +{ + struct sockaddr *addrs = NULL; + unsigned int n_addrs, i; + void *addr_buf; + int rc; + + switch (ip_proto) { + case IPPROTO_SCTP: + break; /* continue below */ + default: + if (*ip_cnt == 0) { + *ip_cnt = 1; + return 0; + } + *ip_cnt = 1; + rc = osmo_sock_get_ip_and_port(fd, ip, ip_len, port, port_len, local); + return rc; + } + + rc = local ? sctp_getladdrs(fd, 0, &addrs) : sctp_getpaddrs(fd, 0, &addrs); + if (rc < 0) + return rc; + if (rc == 0) + return -ENOTCONN; + + n_addrs = rc; + addr_buf = (void *)addrs; + for (i = 0; i < n_addrs; i++) { + struct sockaddr *sa_addr = (struct sockaddr *)addr_buf; + size_t addrlen; + + if (i >= *ip_cnt) + break; + + switch (sa_addr->sa_family) { + case AF_INET: + addrlen = sizeof(struct sockaddr_in); + break; + case AF_INET6: + addrlen = sizeof(struct sockaddr_in6); + break; + default: + local ? sctp_freeladdrs(addrs) : sctp_freepaddrs(addrs); + return -EINVAL; + } + + rc = getnameinfo(sa_addr, addrlen, &ip[i*ip_len], ip_len, + port, port_len, + NI_NUMERICHOST | NI_NUMERICSERV); + if (rc < 0) { + local ? sctp_freeladdrs(addrs) : sctp_freepaddrs(addrs); + return rc; + } + addr_buf += addrlen; + } + + *ip_cnt = n_addrs; + local ? sctp_freeladdrs(addrs) : sctp_freepaddrs(addrs); + return 0; +} + /*! Get local IP address on socket * \param[in] fd file descriptor of socket * \param[out] ip IP address (will be filled in) -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/35179?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Change-Id: I19d560ab4aadec18a4c0f94115675ec1d7ab14d7 Gerrit-Change-Number: 35179 Gerrit-PatchSet: 1 Gerrit-Owner: pespin <pes...@sysmocom.de> Gerrit-MessageType: newchange