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

Reply via email to