From cf7f7924d2700277ac5b90cdaf3203956222e054 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Wed, 2 Feb 2022 03:08:40 +0100 Subject: [PATCH] add osmo_sockaddr_from/to_octets() Shorthand for the INET/INET6 switch() to get/put the addr part, useful for encoding and decoding message buffers. Related: OS#5599 Change-Id: Ie9e33bfac525c59c30714663d2bfcc62ec9eeb81 --- include/osmocom/core/socket.h | 3 ++ src/socket.c | 59 +++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h index 6d11e6f0a..fffc25c7e 100644 --- a/include/osmocom/core/socket.h +++ b/include/osmocom/core/socket.h @@ -127,6 +127,9 @@ int osmo_sockaddr_local_ip(struct osmo_sockaddr *local_ip, int osmo_sockaddr_cmp(const struct osmo_sockaddr *a, const struct osmo_sockaddr *b); +int osmo_sockaddr_to_octets(uint8_t *dst, size_t dst_maxlen, const struct osmo_sockaddr *os); +int osmo_sockaddr_from_octets(struct osmo_sockaddr *os, const void *src, size_t src_len); + const char *osmo_sockaddr_to_str(const struct osmo_sockaddr *sockaddr); char *osmo_sockaddr_to_str_buf(char *buf, size_t buf_len, const struct osmo_sockaddr *sockaddr); diff --git a/src/socket.c b/src/socket.c index 2d19fdf65..6e5bb46fe 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1733,6 +1733,65 @@ int osmo_sockaddr_local_ip(struct osmo_sockaddr *local_ip, const struct osmo_soc return rc; } +/*! Copy the addr part, the IP address octets in network byte order, to a buffer. + * Useful for encoding network protocols. + * \param[out] dst Write octets to this buffer. + * \param[in] dst_maxlen Space available in buffer. + * \param[in] os Sockaddr to copy IP of. + * \return nr of octets written on success, negative on error. + */ +int osmo_sockaddr_to_octets(uint8_t *dst, size_t dst_maxlen, const struct osmo_sockaddr *os) +{ + const void *addr; + size_t len; + switch (os->u.sin.sin_family) { + case AF_INET: + addr = &os->u.sin.sin_addr; + len = sizeof(os->u.sin.sin_addr); + break; + case AF_INET6: + addr = &os->u.sin6.sin6_addr; + len = sizeof(os->u.sin6.sin6_addr); + break; + default: + return -ENOTSUP; + } + if (dst_maxlen < len) + return -ENOSPC; + memcpy(dst, addr, len); + return len; +} + +/*! Copy the addr part, the IP address octets in network byte order, from a buffer. + * Useful for decoding network protocols. + * \param[out] os Write IP address to this sockaddr. + * \param[in] src Source buffer to read IP address octets from. + * \param[in] src_len Number of octets to copy. + * \return number of octets read on success, negative on error. + */ +int osmo_sockaddr_from_octets(struct osmo_sockaddr *os, const void *src, size_t src_len) +{ + void *addr; + size_t len; + *os = (struct osmo_sockaddr){0}; + switch (src_len) { + case sizeof(os->u.sin.sin_addr): + os->u.sin.sin_family = AF_INET; + addr = &os->u.sin.sin_addr; + len = sizeof(os->u.sin.sin_addr); + break; + case sizeof(os->u.sin6.sin6_addr): + os->u.sin6.sin6_family = AF_INET6; + addr = &os->u.sin6.sin6_addr; + len = sizeof(os->u.sin6.sin6_addr); + break; + default: + return -ENOTSUP; + } + memcpy(addr, src, len); + return len; +} + /*! Compare two osmo_sockaddr. * \param[in] a * \param[in] b