socket-util: Replace sockaddr length macros with functions
There's no need for these to be macros, let's just make them regular functions instead.
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <net/if.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/ip.h>
|
||||
@@ -1350,6 +1351,53 @@ void* cmsg_find_and_copy_data(struct msghdr *mh, int level, int type, void *buf,
|
||||
return memcpy_safe(buf, CMSG_DATA(cmsg), buf_len);
|
||||
}
|
||||
|
||||
size_t sockaddr_ll_len(const struct sockaddr_ll *sa) {
|
||||
/* Certain hardware address types (e.g Infiniband) do not fit into sll_addr
|
||||
* (8 bytes) and run over the structure. This function returns the correct size that
|
||||
* must be passed to kernel. */
|
||||
|
||||
assert(sa->sll_family == AF_PACKET);
|
||||
|
||||
size_t mac_len = sizeof(sa->sll_addr);
|
||||
|
||||
if (be16toh(sa->sll_hatype) == ARPHRD_ETHER)
|
||||
mac_len = MAX(mac_len, (size_t) ETH_ALEN);
|
||||
if (be16toh(sa->sll_hatype) == ARPHRD_INFINIBAND)
|
||||
mac_len = MAX(mac_len, (size_t) INFINIBAND_ALEN);
|
||||
|
||||
return offsetof(struct sockaddr_ll, sll_addr) + mac_len;
|
||||
}
|
||||
|
||||
size_t sockaddr_un_len(const struct sockaddr_un *sa) {
|
||||
/* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */
|
||||
|
||||
assert(sa->sun_family == AF_UNIX);
|
||||
|
||||
return offsetof(struct sockaddr_un, sun_path) +
|
||||
(sa->sun_path[0] == 0 ?
|
||||
1 + strnlen(sa->sun_path+1, sizeof(sa->sun_path)-1) :
|
||||
strnlen(sa->sun_path, sizeof(sa->sun_path))+1);
|
||||
}
|
||||
|
||||
size_t sockaddr_len(const union sockaddr_union *sa) {
|
||||
switch (sa->sa.sa_family) {
|
||||
case AF_INET:
|
||||
return sizeof(struct sockaddr_in);
|
||||
case AF_INET6:
|
||||
return sizeof(struct sockaddr_in6);
|
||||
case AF_UNIX:
|
||||
return sockaddr_un_len(&sa->un);
|
||||
case AF_PACKET:
|
||||
return sockaddr_ll_len(&sa->ll);
|
||||
case AF_NETLINK:
|
||||
return sizeof(struct sockaddr_nl);
|
||||
case AF_VSOCK:
|
||||
return sizeof(struct sockaddr_vm);
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
int socket_ioctl_fd(void) {
|
||||
int fd;
|
||||
|
||||
|
||||
+3
-54
@@ -238,62 +238,11 @@ void* cmsg_find_and_copy_data(struct msghdr *mh, int level, int type, void *buf,
|
||||
(size) == CMSG_ALIGN(size) ? 1 : -1]; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Certain hardware address types (e.g Infiniband) do not fit into sll_addr
|
||||
* (8 bytes) and run over the structure. This macro returns the correct size that
|
||||
* must be passed to kernel.
|
||||
*/
|
||||
#define SOCKADDR_LL_LEN(sa) \
|
||||
({ \
|
||||
const struct sockaddr_ll *_sa = &(sa); \
|
||||
size_t _mac_len = sizeof(_sa->sll_addr); \
|
||||
assert(_sa->sll_family == AF_PACKET); \
|
||||
if (be16toh(_sa->sll_hatype) == ARPHRD_ETHER) \
|
||||
_mac_len = MAX(_mac_len, (size_t) ETH_ALEN); \
|
||||
if (be16toh(_sa->sll_hatype) == ARPHRD_INFINIBAND) \
|
||||
_mac_len = MAX(_mac_len, (size_t) INFINIBAND_ALEN); \
|
||||
offsetof(struct sockaddr_ll, sll_addr) + _mac_len; \
|
||||
})
|
||||
size_t sockaddr_ll_len(const struct sockaddr_ll *sa);
|
||||
|
||||
/* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */
|
||||
#define SOCKADDR_UN_LEN(sa) \
|
||||
({ \
|
||||
const struct sockaddr_un *_sa = &(sa); \
|
||||
assert(_sa->sun_family == AF_UNIX); \
|
||||
offsetof(struct sockaddr_un, sun_path) + \
|
||||
(_sa->sun_path[0] == 0 ? \
|
||||
1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \
|
||||
strnlen(_sa->sun_path, sizeof(_sa->sun_path))+1); \
|
||||
})
|
||||
size_t sockaddr_un_len(const struct sockaddr_un *sa);
|
||||
|
||||
#define SOCKADDR_LEN(saddr) \
|
||||
({ \
|
||||
const union sockaddr_union *__sa = &(saddr); \
|
||||
size_t _len; \
|
||||
switch (__sa->sa.sa_family) { \
|
||||
case AF_INET: \
|
||||
_len = sizeof(struct sockaddr_in); \
|
||||
break; \
|
||||
case AF_INET6: \
|
||||
_len = sizeof(struct sockaddr_in6); \
|
||||
break; \
|
||||
case AF_UNIX: \
|
||||
_len = SOCKADDR_UN_LEN(__sa->un); \
|
||||
break; \
|
||||
case AF_PACKET: \
|
||||
_len = SOCKADDR_LL_LEN(__sa->ll); \
|
||||
break; \
|
||||
case AF_NETLINK: \
|
||||
_len = sizeof(struct sockaddr_nl); \
|
||||
break; \
|
||||
case AF_VSOCK: \
|
||||
_len = sizeof(struct sockaddr_vm); \
|
||||
break; \
|
||||
default: \
|
||||
assert_not_reached(); \
|
||||
} \
|
||||
_len; \
|
||||
})
|
||||
size_t sockaddr_len(const union sockaddr_union *sa);
|
||||
|
||||
int socket_ioctl_fd(void);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user