aboutsummaryrefslogtreecommitdiffstats
path: root/src/socket.c
diff options
context:
space:
mode:
authorOliver Smith <osmith@sysmocom.de>2018-10-25 11:16:36 +0200
committerHarald Welte <laforge@gnumonks.org>2018-10-26 17:54:16 +0000
commit7acd5d039491a14a05b6aa08890d28590dde8b96 (patch)
tree8636060ce73f1259c7c60a9df518adccff823282 /src/socket.c
parente74f49d973da4d6dce741deee0d249e5848d06ce (diff)
add osmo_sock_get_{local,remote}_ip{,_port}()
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
Diffstat (limited to 'src/socket.c')
-rw-r--r--src/socket.c111
1 files changed, 86 insertions, 25 deletions
diff --git a/src/socket.c b/src/socket.c
index bb5505f9..c7e1c9dd 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)
+static 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);
}