#include <net/if.h>
#include <sys/ioctl.h>
#include <linux/ethtool.h>
+#include <linux/netdevice.h>
#include <linux/sockios.h>
#include "conf-parser.h"
return 0;
}
+int ethtool_get_permanent_macaddr(int *fd, const char *ifname, struct ether_addr *ret) {
+ _cleanup_free_ struct ethtool_perm_addr *epaddr = NULL;
+ struct ifreq ifr;
+ int r;
+
+ assert(fd);
+ assert(ifname);
+ assert(ret);
+
+ if (*fd < 0) {
+ r = ethtool_connect_or_warn(fd, false);
+ if (r < 0)
+ return r;
+ }
+
+ epaddr = malloc(offsetof(struct ethtool_perm_addr, data) + MAX_ADDR_LEN);
+ if (!epaddr)
+ return -ENOMEM;
+
+ epaddr->cmd = ETHTOOL_GPERMADDR;
+ epaddr->size = MAX_ADDR_LEN;
+
+ ifr = (struct ifreq) {
+ .ifr_data = (caddr_t) epaddr,
+ };
+ strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
+
+ r = ioctl(*fd, SIOCETHTOOL, &ifr);
+ if (r < 0)
+ return -errno;
+
+ if (epaddr->size != 6)
+ return -EOPNOTSUPP;
+
+ for (size_t i = 0; i < epaddr->size; i++)
+ ret->ether_addr_octet[i] = epaddr->data[i];
+
+ return 0;
+}
+
int ethtool_set_speed(int *fd, const char *ifname, unsigned speed, Duplex duplex) {
struct ethtool_cmd ecmd = {
.cmd = ETHTOOL_GSET
#pragma once
#include <macro.h>
+#include <net/ethernet.h>
#include <linux/ethtool.h>
#include "conf-parser.h"
int ethtool_get_link_info(int *fd, const char *ifname,
int *ret_autonegotiation, size_t *ret_speed,
Duplex *ret_duplex, NetDevPort *ret_port);
+int ethtool_get_permanent_macaddr(int *fd, const char *ifname, struct ether_addr *ret);
int ethtool_set_speed(int *fd, const char *ifname, unsigned speed, Duplex duplex);
int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol);
int ethtool_set_nic_buffer_size(int *fd, const char *ifname, netdev_ring_param *ring);