diff --git a/src/common/sockaddr.c b/src/common/sockaddr.c index 40e23122ec68052a4b2b16da8424e2e45f1c3ade..eb9a133210689dbc37b42e387662603742948b9a 100644 --- a/src/common/sockaddr.c +++ b/src/common/sockaddr.c @@ -81,28 +81,35 @@ int sockaddr_set(struct sockaddr_storage *ss, int family, const char *straddr, i return KNOT_EINVAL; } -int sockaddr_set_raw(struct sockaddr_storage *ss, int family, const uint8_t *raw_addr) +int sockaddr_set_raw(struct sockaddr_storage *ss, int family, + const uint8_t *raw_addr, size_t raw_addr_size) { if (ss == NULL || raw_addr == NULL) { return KNOT_EINVAL; } - /* Clear the structure and set family and port. */ - memset(ss, 0, sizeof(struct sockaddr_storage)); - ss->ss_family = family; + void *sa_data = NULL; + size_t sa_size = 0; - /* Initialize address depending on address family. */ - if (family == AF_INET6) { - struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)ss; - memcpy(&ipv6->sin6_addr, raw_addr, sizeof(ipv6->sin6_addr)); - return KNOT_EOK; - } else if (family == AF_INET) { + if (family == AF_INET) { struct sockaddr_in *ipv4 = (struct sockaddr_in *)ss; - memcpy(&ipv4->sin_addr, raw_addr, sizeof(ipv4->sin_addr)); - return KNOT_EOK; + sa_data = &ipv4->sin_addr; + sa_size = sizeof(ipv4->sin_addr); + } else if (family == AF_INET6) { + struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)ss; + sa_data = &ipv6->sin6_addr; + sa_size = sizeof(ipv6->sin6_addr); } - return KNOT_EINVAL; + if (sa_data == NULL || sa_size != raw_addr_size) { + return KNOT_EINVAL; + } + + memset(ss, 0, sizeof(*ss)); + ss->ss_family = family; + memcpy(sa_data, raw_addr, sa_size); + + return KNOT_EOK; } int sockaddr_tostr(const struct sockaddr_storage *ss, char *buf, size_t maxlen) diff --git a/src/common/sockaddr.h b/src/common/sockaddr.h index 3fc5a8b79633b39a90d719532bab9245de544376..b0128d05c00a0f54ab060981d5cee4dd77800e67 100644 --- a/src/common/sockaddr.h +++ b/src/common/sockaddr.h @@ -79,15 +79,15 @@ int sockaddr_set(struct sockaddr_storage *ss, int family, const char *straddr, i /*! * \brief Set raw address. * - * @note It is the caller's responsibility of have correct raw_addr length. - * * \param ss Socket address storage. * \param family Address family. - * \param addr IP address in binary format. + * \param raw_addr IP address in binary format. + * \param raw_addr_size Size of the binary address. * * return KNOT_EOK on success or an error code */ -int sockaddr_set_raw(struct sockaddr_storage *ss, int family, const uint8_t *raw_addr); +int sockaddr_set_raw(struct sockaddr_storage *ss, int family, + const uint8_t *raw_addr, size_t raw_addr_size); /*! * \brief Return string representation of socket address.