aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Smith <osmith@sysmocom.de>2018-10-25 11:16:36 +0200
committerOliver Smith <osmith@sysmocom.de>2018-10-26 16:35:33 +0200
commit4e91c44704b1284bb8fca83f0bed6a393c6678c3 (patch)
treef0b614b713c174c3f228431ebd697645bd28e787
parente74f49d973da4d6dce741deee0d249e5848d06ce (diff)
add osmo_sock_get_{local,remote}_ip{,_port}()osmith/new-osmo-sock-functions
Return only the IP or port of either the local or remote connection, not the whole set of IP and port of both the local and remote connection like osmo_sock_get_name() does it. This is needed for OS#2841, where we only want to print the remote IP. Related: OS#2841 Change-Id: I6803c204771c59a2002bc6a0e6b79c83c35f87e1
-rw-r--r--include/osmocom/core/socket.h6
-rw-r--r--src/socket.c111
2 files changed, 92 insertions, 25 deletions
diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h
index f23a243..28f89a5 100644
--- a/include/osmocom/core/socket.h
+++ b/include/osmocom/core/socket.h
@@ -9,6 +9,7 @@
#include <stdint.h>
#include <stdbool.h>
+#include <stddef.h>
struct sockaddr;
struct osmo_fd;
@@ -56,6 +57,11 @@ int osmo_sock_unix_init_ofd(struct osmo_fd *ofd, uint16_t type, uint8_t proto,
const char *socket_path, unsigned int flags);
char *osmo_sock_get_name(void *ctx, int fd);
+int osmo_sock_get_local_ip(int fd, char *host, size_t len);
+int osmo_sock_get_local_ip_port(int fd, char *port, size_t len);
+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_mcast_loop_set(int fd, bool enable);
int osmo_sock_mcast_ttl_set(int fd, uint8_t ttl);
diff --git a/src/socket.c b/src/socket.c
index bb5505f..781e8b1 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -682,44 +682,105 @@ int osmo_sock_unix_init_ofd(struct osmo_fd *ofd, uint16_t type, uint8_t proto,
return osmo_fd_init_ofd(ofd, osmo_sock_unix_init(type, proto, socket_path, flags));
}
-/*! Get address/port information on socket in dyn-alloc string
- * \param[in] ctx talloc context from which to allocate string buffer
+/*! Get the IP and/or port number on socket. This is for internal usage.
+ * Convenience wrappers: osmo_sock_get_local_ip(),
+ * osmo_sock_get_local_ip_port(), osmo_sock_get_remote_ip(),
+ * osmo_sock_get_remote_ip_port() and osmo_sock_get_name()
* \param[in] fd file descriptor of socket
- * \returns string identifying the connection of this socket
+ * \param[out] ip IP address (will be filled in when not NULL)
+ * \param[in] ip_len length of the ip buffer
+ * \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
*/
-char *osmo_sock_get_name(void *ctx, int fd)
+int osmo_sock_get_name2(int fd, char *ip, size_t ip_len, char *port, size_t port_len, bool local)
{
- struct sockaddr sa_l, sa_r;
- socklen_t sa_len_l = sizeof(sa_l);
- socklen_t sa_len_r = sizeof(sa_r);
- char hostbuf_l[64], hostbuf_r[64];
- char portbuf_l[16], portbuf_r[16];
+ struct sockaddr sa;
+ socklen_t len = sizeof(sa);
+ char ipbuf[64], portbuf[16];
int rc;
- rc = getsockname(fd, &sa_l, &sa_len_l);
+ rc = local ? getsockname(fd, &sa, &len) : getpeername(fd, &sa, &len);
if (rc < 0)
- return NULL;
+ return rc;
- rc = getnameinfo(&sa_l, sa_len_l, hostbuf_l, sizeof(hostbuf_l),
- portbuf_l, sizeof(portbuf_l),
+ rc = getnameinfo(&sa, len, ipbuf, sizeof(ipbuf),
+ portbuf, sizeof(portbuf),
NI_NUMERICHOST | NI_NUMERICSERV);
if (rc < 0)
- return NULL;
+ return rc;
- rc = getpeername(fd, &sa_r, &sa_len_r);
- if (rc < 0)
- goto local_only;
+ if (ip)
+ strncpy(ip, ipbuf, ip_len);
+ if (port)
+ strncpy(port, portbuf, port_len);
+ return 0;
+}
- rc = getnameinfo(&sa_r, sa_len_r, hostbuf_r, sizeof(hostbuf_r),
- portbuf_r, sizeof(portbuf_r),
- NI_NUMERICHOST | NI_NUMERICSERV);
- if (rc < 0)
- goto local_only;
+/*! Get local IP address on socket
+ * \param[in] fd file descriptor of socket
+ * \param[out] ip IP address (will be filled in)
+ * \param[in] len length of the output buffer
+ * \returns 0 on success; negative otherwise
+ */
+int osmo_sock_get_local_ip(int fd, char *ip, size_t len)
+{
+ return osmo_sock_get_name2(fd, ip, len, NULL, 0, true);
+}
+
+/*! Get local port on socket
+ * \param[in] fd file descriptor of socket
+ * \param[out] port number (will be filled in)
+ * \param[in] len length of the output buffer
+ * \returns 0 on success; negative otherwise
+ */
+int osmo_sock_get_local_ip_port(int fd, char *port, size_t len)
+{
+ return osmo_sock_get_name2(fd, NULL, 0, port, len, true);
+}
+
+/*! Get remote IP address on socket
+ * \param[in] fd file descriptor of socket
+ * \param[out] ip IP address (will be filled in)
+ * \param[in] len length of the output buffer
+ * \returns 0 on success; negative otherwise
+ */
+int osmo_sock_get_remote_ip(int fd, char *ip, size_t len)
+{
+ return osmo_sock_get_name2(fd, ip, len, NULL, 0, false);
+}
+
+/*! Get remote port on socket
+ * \param[in] fd file descriptor of socket
+ * \param[out] port number (will be filled in)
+ * \param[in] len length of the output buffer
+ * \returns 0 on success; negative otherwise
+ */
+int osmo_sock_get_remote_ip_port(int fd, char *port, size_t len)
+{
+ return osmo_sock_get_name2(fd, NULL, 0, port, len, false);
+}
+
+/*! Get address/port information on socket in dyn-alloc string
+ * \param[in] ctx talloc context from which to allocate string buffer
+ * \param[in] fd file descriptor of socket
+ * \returns string identifying the connection of this socket
+ */
+char *osmo_sock_get_name(void *ctx, int fd)
+{
+ char hostbuf_l[64], hostbuf_r[64];
+ char portbuf_l[16], portbuf_r[16];
+
+ /* get local */
+ if (osmo_sock_get_name2(fd, hostbuf_l, sizeof(hostbuf_l), portbuf_l, sizeof(portbuf_l), true))
+ return NULL;
- return talloc_asprintf(ctx, "(r=%s:%s<->l=%s:%s)", hostbuf_r, portbuf_r,
- hostbuf_l, portbuf_l);
+ /* get remote */
+ if (!osmo_sock_get_name2(fd, hostbuf_r, sizeof(hostbuf_r), portbuf_r, sizeof(portbuf_r), false))
+ return talloc_asprintf(ctx, "(r=%s:%s<->l=%s:%s)", hostbuf_r, portbuf_r, hostbuf_l, portbuf_l);
-local_only:
+ /* local only: different format */
return talloc_asprintf(ctx, "(r=NULL<->l=%s:%s)", hostbuf_l, portbuf_l);
}