#include <netinet/in.h>
#include <sys/un.h>
+#ifdef HOST_OS_LINUX
+# include <linux/ethtool.h>
+#endif
+
#if HAVE_VFORK_H
# include <vfork.h>
#endif
# include "protocols/edp.h"
#endif
+
+
#include "../compat/compat.h"
#include "../marshal.h"
#include "../log.h"
#ifdef HOST_OS_LINUX
int priv_open(char*);
void asroot_open(void);
-int priv_ethtool(char*, void*, size_t);
+int priv_ethtool(char*, struct ethtool_cmd*);
+# ifdef ENABLE_OLDIES
void asroot_ethtool(void);
+# endif
#endif
int priv_iface_init(int, char *);
int asroot_iface_init_os(int, char *, int *);
return receive_fd(PRIV_UNPRIVILEGED);
}
+static int
+asroot_ethtool_real(const char *ifname, struct ethtool_cmd *ethc) {
+ int rc, sock = -1;
+ struct ifreq ifr = {
+ .ifr_data = (caddr_t)ethc
+ };
+ strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+
+ memset(ethc, 0, sizeof(struct ethtool_cmd));
+ ethc->cmd = ETHTOOL_GSET;
+ if (((rc = sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) ||
+ (rc = ioctl(sock, SIOCETHTOOL, &ifr)) != 0) {
+ if (sock != -1) close(sock);
+ return rc;
+ }
+ close(sock);
+ return rc;
+}
+
/* Proxy for ethtool ioctl (GSET only). Not needed since
- * 0fdc100bdc4b7ab61ed632962c76dfe539047296 (2.6.37) */
+ * 0fdc100bdc4b7ab61ed632962c76dfe539047296 (2.6.37). */
int
-priv_ethtool(char *ifname, void *ethc, size_t length)
+priv_ethtool(char *ifname, struct ethtool_cmd *ethc)
{
- int rc, len;
+ int rc;
+#ifdef ENABLE_OLDIES
+ int len;
enum priv_cmd cmd = PRIV_ETHTOOL;
must_write(PRIV_UNPRIVILEGED, &cmd, sizeof(enum priv_cmd));
len = strlen(ifname);
must_read(PRIV_UNPRIVILEGED, &rc, sizeof(int));
if (rc != 0)
return rc;
- must_read(PRIV_UNPRIVILEGED, ethc, length);
+ must_read(PRIV_UNPRIVILEGED, ethc, sizeof(struct ethtool_cmd));
+#else
+ rc = asroot_ethtool_real(ifname, ethc);
+#endif
return rc;
}
close(fd);
}
+#ifdef ENABLE_OLDIES
void
asroot_ethtool()
{
- struct ifreq ifr = {};
- struct ethtool_cmd ethc = {};
- int len, rc, sock = -1;
+ struct ethtool_cmd ethc;
+ int len, rc;
char *ifname;
must_read(PRIV_PRIVILEGED, &len, sizeof(int));
fatal("privsep", NULL);
must_read(PRIV_PRIVILEGED, ifname, len);
ifname[len] = '\0';
- strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+ rc = asroot_ethtool_real(ifname, ðc);
free(ifname);
- ifr.ifr_data = (caddr_t)ðc;
- ethc.cmd = ETHTOOL_GSET;
- if (((rc = sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) ||
- (rc = ioctl(sock, SIOCETHTOOL, &ifr)) != 0) {
- if (sock != -1) close(sock);
- must_write(PRIV_PRIVILEGED, &rc, sizeof(int));
- return;
- }
- close(sock);
must_write(PRIV_PRIVILEGED, &rc, sizeof(int));
+ if (rc == -1) return;
must_write(PRIV_PRIVILEGED, ðc, sizeof(struct ethtool_cmd));
}
+#endif
int
asroot_iface_init_os(int ifindex, char *name, int *fd)