#include <assert.h>
#include <stdio.h>
+#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
case AF_INET6:
return sizeof(struct sockaddr_in6);
case AF_UNIX:
- return sizeof(struct sockaddr_un);
+ ; const struct sockaddr_un *un = (const struct sockaddr_un *)ss;
+ return offsetof(struct sockaddr_un, sun_path) + strlen(un->sun_path) + 1;
default:
return 0;
}
return &ipv6->sin6_addr;
} else if (ss->ss_family == AF_UNIX) {
struct sockaddr_un *un = (struct sockaddr_un *)ss;
- *addr_size = sizeof(un->sun_path);
+ *addr_size = offsetof(struct sockaddr_un, sun_path) +
+ strlen(un->sun_path) + 1;
return un->sun_path;
} else {
return NULL;
void *ss_data = sockaddr_raw(ss, &ss_size);
if (ss_data == NULL ||
(family != AF_UNIX && ss_size != raw_addr_size) ||
- (family == AF_UNIX && ss_size <= raw_addr_size)) {
+ (family == AF_UNIX && raw_addr_size >= sizeof((struct sockaddr_un *)ss)->sun_path)) {
return KNOT_EINVAL;
}
return false;
}
- size_t raw_len = 0;
- const uint8_t *raw_1 = sockaddr_raw(ss1, &raw_len);
- const uint8_t *raw_2 = sockaddr_raw(ss2, &raw_len);
+ if (ss1->ss_family == AF_UNIX) {
+ const struct sockaddr_un *un1 = (const struct sockaddr_un *)ss1;
+ const struct sockaddr_un *un2 = (const struct sockaddr_un *)ss2;
+ return strcmp(un1->sun_path, un2->sun_path) == 0;
+ } else {
+ size_t raw_len = 0;
+ const uint8_t *raw_1 = sockaddr_raw(ss1, &raw_len);
+ const uint8_t *raw_2 = sockaddr_raw(ss2, &raw_len);
- prefix = MIN(prefix, raw_len * 8);
- unsigned bytes = prefix / 8;
- unsigned bits = prefix % 8;
+ prefix = MIN(prefix, raw_len * 8);
+ unsigned bytes = prefix / 8;
+ unsigned bits = prefix % 8;
- /* Compare full bytes. */
- if (memcmp(raw_1, raw_2, bytes) != 0) {
- return false;
- }
+ /* Compare full bytes. */
+ if (memcmp(raw_1, raw_2, bytes) != 0) {
+ return false;
+ }
- /* Compare last partial byte. */
- return bits == 0 ||
- (raw_1[bytes] >> (8 - bits) == raw_2[bytes] >> (8 - bits));
+ /* Compare last partial byte. */
+ return bits == 0 ||
+ (raw_1[bytes] >> (8 - bits) == raw_2[bytes] >> (8 - bits));
+ }
}
bool sockaddr_range_match(const struct sockaddr_storage *ss,
}
if (ss_min->ss_family != ss_max->ss_family ||
- ss_min->ss_family != ss->ss_family) {
+ ss_min->ss_family != ss->ss_family ||
+ ss->ss_family == AF_UNIX) {
return false;
}
/*!
* \brief Calculate current structure length based on address family.
*
- * \param ss Socket address.
+ * \param ss Socket address (can be sockaddr_t).
*
* \return Number of bytes or error code.
*/
/*!
* \brief Compare addresses.
*
- * \param a First address.
- * \param b Second address.
+ * \param a First address (can be sockaddr_t).
+ * \param b Second address (can be sockaddr_t).
* \param ignore_port Ignore port indication.
*
* \return like memcmp(3)
/*!
* \brief Set address and port.
*
- * \param ss Socket address.
+ * \param ss Socket address (CANNOT be sockaddr_t!).
* \param family Address family.
* \param straddr IP address in string format.
* \param port Port.
/*!
* \brief Return raw network address in network byte order.
*
- * \param[in] ss Socket address.
+ * \param[in] ss Socket address (can be sockaddr_t).
* \param[out] addr_size Address length.
*
* \return Pointer to binary buffer of size addr_size.
/*!
* \brief Set raw address.
*
- * \param ss Socket address.
+ * \param ss Socket address (CANNOT be sockaddr_t!).
* \param family Address family.
* \param raw_addr IP address in binary format.
* \param raw_addr_size Size of the binary address.
*
* \param buf Destination for string representation.
* \param maxlen Maximum number of written bytes.
- * \param ss Socket address.
+ * \param ss Socket address (can be sockaddr_t).
*
* \return Number of bytes written on success, error code on failure.
*/
/*!
* \brief Check if address is ANY address.
*
- * \param ss Socket address.
+ * \param ss Socket address (can be sockaddr_t).
*/
bool sockaddr_is_any(const struct sockaddr_storage *ss);
/*!
* \brief Check if two addresses match the given network prefix.
*
- * \param ss1 First address.
- * \param ss2 Second address.
+ * \param ss1 First address (can be sockaddr_t).
+ * \param ss2 Second address (can be sockaddr_t).
* \param prefix Prefix length.
*
* \return True on match.
/*!
* \brief Check if the address is within the given address range (inclusive).
*
- * \param ss Address to check.
- * \param ss_min Minimum address.
- * \param ss_max Maximum address.
+ * \param ss Address to check (can be sockaddr_t).
+ * \param ss_min Minimum address (can be sockaddr_t).
+ * \param ss_max Maximum address (can be sockaddr_t).
*
* \return True on match.
*/