diff options
author | Timo Rothenpieler <timo@rothenpieler.org> | 2020-10-26 16:22:13 +0100 |
---|---|---|
committer | Timo Rothenpieler <timo@rothenpieler.org> | 2020-10-28 14:44:43 +0100 |
commit | 4fc8a29a7e06debb65f4e2651a03804beb41f781 (patch) | |
tree | 86209a9c7d55c72cbd7d08f4e3cb874c53277ba8 /src/libsystemd | |
parent | 48625dc437589d328de09887d1ebc360233f5acf (diff) | |
download | systemd-4fc8a29a7e06debb65f4e2651a03804beb41f781.tar.gz |
sd-netlink: introduce netlink_message_{read,append}_hw_addr
Hardware addresses come in various shapes and sizes, these new functions
and accomapying data structures account for that instead of hard-coding
a hardware address to the 6 bytes of an ethernet MAC.
Diffstat (limited to 'src/libsystemd')
-rw-r--r-- | src/libsystemd/sd-netlink/netlink-message.c | 43 | ||||
-rw-r--r-- | src/libsystemd/sd-netlink/netlink-util.h | 3 |
2 files changed, 46 insertions, 0 deletions
diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index da4f5ba688..2ffff861b2 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -495,6 +495,25 @@ int sd_netlink_message_append_ether_addr(sd_netlink_message *m, unsigned short t return 0; } +int netlink_message_append_hw_addr(sd_netlink_message *m, unsigned short type, const hw_addr_data *data) { + int r; + + assert_return(m, -EINVAL); + assert_return(!m->sealed, -EPERM); + assert_return(data, -EINVAL); + assert_return(data->length > 0, -EINVAL); + + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_ETHER_ADDR); + if (r < 0) + return r; + + r = add_rtattr(m, type, data->addr.bytes, data->length); + if (r < 0) + return r; + + return 0; +} + int sd_netlink_message_append_cache_info(sd_netlink_message *m, unsigned short type, const struct ifa_cacheinfo *info) { int r; @@ -864,6 +883,30 @@ int sd_netlink_message_read_ether_addr(sd_netlink_message *m, unsigned short typ return 0; } +int netlink_message_read_hw_addr(sd_netlink_message *m, unsigned short type, hw_addr_data *data) { + int r; + void *attr_data; + + assert_return(m, -EINVAL); + + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_ETHER_ADDR); + if (r < 0) + return r; + + r = netlink_message_read_internal(m, type, &attr_data, NULL); + if (r < 0) + return r; + else if ((size_t) r > sizeof(union hw_addr_union)) + return -EIO; + + if (data) { + memcpy(data->addr.bytes, attr_data, r); + data->length = r; + } + + return 0; +} + int sd_netlink_message_read_cache_info(sd_netlink_message *m, unsigned short type, struct ifa_cacheinfo *info) { int r; void *attr_data; diff --git a/src/libsystemd/sd-netlink/netlink-util.h b/src/libsystemd/sd-netlink/netlink-util.h index 2768d5fdc4..8f6c06af6e 100644 --- a/src/libsystemd/sd-netlink/netlink-util.h +++ b/src/libsystemd/sd-netlink/netlink-util.h @@ -5,6 +5,7 @@ #include "sd-netlink.h" +#include "ether-addr-util.h" #include "in-addr-util.h" #include "ordered-set.h" #include "socket-util.h" @@ -100,9 +101,11 @@ int rtnl_log_create_error(int r); userdata, description); \ }) +int netlink_message_append_hw_addr(sd_netlink_message *m, unsigned short type, const hw_addr_data *data); int netlink_message_append_in_addr_union(sd_netlink_message *m, unsigned short type, int family, const union in_addr_union *data); int netlink_message_append_sockaddr_union(sd_netlink_message *m, unsigned short type, const union sockaddr_union *data); +int netlink_message_read_hw_addr(sd_netlink_message *m, unsigned short type, hw_addr_data *data); int netlink_message_read_in_addr_union(sd_netlink_message *m, unsigned short type, int family, union in_addr_union *data); void rtattr_append_attribute_internal(struct rtattr *rta, unsigned short type, const void *data, size_t data_length); |