summaryrefslogtreecommitdiff
path: root/ethtool.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@vyatta.com>2010-11-16 19:14:33 +0000
committerBen Hutchings <bhutchings@solarflare.com>2010-11-16 19:16:01 +0000
commitfef1c4a19703ddf939dd7ef18e3994134dc2aea0 (patch)
treebd466bb33d38e1ac2d1c1e7fef577d3e9fb14a3a /ethtool.c
parent02ea0ac03e3a79401c00349a7a69c3643913f52b (diff)
downloadethtool-fef1c4a19703ddf939dd7ef18e3994134dc2aea0.tar.gz
ethtool: add get permanent address option
Add command level support for showing permanent address. The ioctl has been around for a long time but there was no option to display it. Note: MAX_ADDR_LEN is defined in netdevice.h but including netdevice.h leads to multiple definition errors with if.h. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> [bwh: Fix use of '|' in place of '||', as noted by Joe Perches] Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'ethtool.c')
-rw-r--r--ethtool.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/ethtool.c b/ethtool.c
index 3098c84..4b7672c 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -53,6 +53,9 @@
#ifndef SIOCETHTOOL
#define SIOCETHTOOL 0x8946
#endif
+#ifndef MAX_ADDR_LEN
+#define MAX_ADDR_LEN 32
+#endif
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
@@ -110,6 +113,8 @@ static int do_srxfhindir(int fd, struct ifreq *ifr);
static int do_srxntuple(int fd, struct ifreq *ifr);
static int do_grxntuple(int fd, struct ifreq *ifr);
static int do_flash(int fd, struct ifreq *ifr);
+static int do_permaddr(int fd, struct ifreq *ifr);
+
static int send_ioctl(int fd, struct ifreq *ifr);
static enum {
@@ -139,6 +144,7 @@ static enum {
MODE_SNTUPLE,
MODE_GNTUPLE,
MODE_FLASHDEV,
+ MODE_PERMADDR,
} mode = MODE_GSET;
static struct option {
@@ -256,6 +262,8 @@ static struct option {
" action N\n" },
{ "-u", "--show-ntuple", MODE_GNTUPLE,
"Get Rx ntuple filters and actions\n" },
+ { "-P", "--show-permaddr", MODE_PERMADDR,
+ "Show permanent hardware address" },
{ "-h", "--help", MODE_HELP, "Show this help" },
{}
};
@@ -826,7 +834,8 @@ static void parse_cmdline(int argc, char **argp)
(mode == MODE_SNTUPLE) ||
(mode == MODE_GNTUPLE) ||
(mode == MODE_PHYS_ID) ||
- (mode == MODE_FLASHDEV)) {
+ (mode == MODE_FLASHDEV) ||
+ (mode == MODE_PERMADDR)) {
devname = argp[i];
break;
}
@@ -1997,6 +2006,8 @@ static int doit(void)
return do_grxntuple(fd, &ifr);
} else if (mode == MODE_FLASHDEV) {
return do_flash(fd, &ifr);
+ } else if (mode == MODE_PERMADDR) {
+ return do_permaddr(fd, &ifr);
}
return 69;
@@ -3079,6 +3090,31 @@ static int do_flash(int fd, struct ifreq *ifr)
return err;
}
+static int do_permaddr(int fd, struct ifreq *ifr)
+{
+ int i, err;
+ struct ethtool_perm_addr *epaddr;
+
+ epaddr = malloc(sizeof(struct ethtool_perm_addr) + MAX_ADDR_LEN);
+ epaddr->cmd = ETHTOOL_GPERMADDR;
+ epaddr->size = MAX_ADDR_LEN;
+ ifr->ifr_data = (caddr_t)epaddr;
+
+ err = send_ioctl(fd, ifr);
+ if (err < 0)
+ perror("Cannot read permanent address");
+ else {
+ printf("Permanent address:");
+ for (i = 0; i < epaddr->size; i++)
+ printf("%c%02x", (i == 0) ? ' ' : ':',
+ epaddr->data[i]);
+ printf("\n");
+ }
+ free(epaddr);
+
+ return err;
+}
+
static int do_srxntuple(int fd, struct ifreq *ifr)
{
int err;