tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

interface name optional in wake(8)



Make the interface name argument to wake(8) optional. If the first argument
given to wake(8) is not the name of a local ethernet interface, wake(8)
determines the first ethernet device in the system and uses it instead.

With the interface name being optional, scripts using wake(8) can work
unaltered on machines with different ethernet devices.

Comments?  Like/Dislike?

Index: usr.sbin/wake/wake.8
===================================================================
RCS file: /cvsroot/src/usr.sbin/wake/wake.8,v
retrieving revision 1.5
diff -u -p -r1.5 wake.8
--- usr.sbin/wake/wake.8        21 Dec 2009 15:48:33 -0000      1.5
+++ usr.sbin/wake/wake.8        3 Jan 2010 10:12:23 -0000
@@ -1,6 +1,6 @@
 .\" $NetBSD: wake.8,v 1.5 2009/12/21 15:48:33 mbalmer Exp $
 .\"
-.\" Copyright (c) 2009 Marc Balmer <marc%msys.ch@localhost>
+.\" Copyright (c) 2009, 2010 Marc Balmer <marc%msys.ch@localhost>
 .\"
 .\" Permission to use, copy, modify, and distribute this software for any
 .\" purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd December 21, 2009
+.Dd January 3, 2010
 .Dt WAKE 8
 .Os
 .Sh NAME
@@ -22,7 +22,7 @@
 .Nd send Wake on LAN frames to hosts on a local Ethernet network
 .Sh SYNOPSIS
 .Nm
-.Ar interface
+.Op Ar interface
 .Ar lladdr
 .Op Ar lladdr ...
 .Sh DESCRIPTION
@@ -35,8 +35,13 @@ WoL functionality is generally enabled i
 and can be used to power on machines from a remote system without
 having physical access to them.
 .Pp
+If
 .Ar interface
-is a network interface of the local machine.
+is an ethernet interface of the local machine, it is used to send the
+Wake on LAN frames over it.
+Else
+.Nm
+uses the first ethernet device found in the system.
 .Ar lladdr
 is the link layer address of the remote machine.
 This can be specified as the actual hardware address
Index: usr.sbin/wake/wake.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/wake/wake.c,v
retrieving revision 1.9
diff -u -p -r1.9 wake.c
--- usr.sbin/wake/wake.c        21 Dec 2009 08:42:39 -0000      1.9
+++ usr.sbin/wake/wake.c        3 Jan 2010 10:12:23 -0000
@@ -1,7 +1,7 @@
 /* $NetBSD: wake.c,v 1.9 2009/12/21 08:42:39 mbalmer Exp $ */
 
 /*
- * Copyright (C) 2006, 2007, 2008, 2009 Marc Balmer <marc%msys.ch@localhost>
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Marc Balmer 
<marc%msys.ch@localhost>
  * Copyright (C) 2000 Eugene M. Kim.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,8 +34,11 @@
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/time.h>
+
 #include <net/bpf.h>
 #include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
 
 #include <netinet/in.h>
 #include <netinet/if_ether.h>
@@ -43,6 +46,7 @@
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <ifaddrs.h>
 #include <limits.h>
 #include <paths.h>
 #include <stdarg.h>
@@ -63,6 +67,7 @@
 static __dead void usage(void);
 static int wake(int, const char *);
 static int bind_if_to_bpf(char const *, int);
+static int find_ether(char *, size_t);
 static int get_ether(char const *, struct ether_addr *);
 static int send_wakeup(int, struct ether_addr const *);
 
@@ -108,6 +113,31 @@ bind_if_to_bpf(char const *ifname, int b
 }
 
 static int
+find_ether(char *dst, size_t len)
+{
+       struct ifaddrs *ifap, *ifa;
+       struct sockaddr_dl *sdl = NULL;
+
+       if (dst == NULL || len == 0)
+               return 0;
+
+       if (getifaddrs(&ifap) != 0)
+               return -1;
+
+       for (ifa = ifap; ifa; ifa = ifa->ifa_next)
+               if (ifa->ifa_addr->sa_family == AF_LINK) {
+                       sdl = (struct sockaddr_dl *)ifa->ifa_addr;
+                       if (sdl->sdl_type == IFT_ETHER) {
+                               strlcpy(dst, ifa->ifa_name, len);
+                               break;
+                       }
+               }
+
+       freeifaddrs(ifap);
+       return 0;
+}
+
+static int
 get_ether(char const *text, struct ether_addr *addr)
 {
        struct ether_addr *paddr;
@@ -156,19 +186,30 @@ int
 main(int argc, char *argv[])
 {
        int bpf, n;
+       char ifname[32];
 
-       if (argc < 3)
+       if (argc < 2)
                usage();
 
        if ((bpf = open(_PATH_BPF, O_RDWR)) == -1)
                err(EXIT_FAILURE, "Cannot open bpf interface");
 
-       if (bind_if_to_bpf(argv[1], bpf) == -1)
-               err(EXIT_FAILURE, "Cannot bind to interface `%s'", argv[1]);
+       n = 2;
+
+       if (bind_if_to_bpf(argv[1], bpf) == -1) {
+               if (find_ether(ifname, sizeof(ifname)))
+                       err(EXIT_FAILURE, "Failed to determine ethernet "
+                           "interface");
+               if (bind_if_to_bpf(ifname, bpf) == -1)
+                       err(EXIT_FAILURE, "Cannot bind to interface `%s'",
+                           ifname);
+               --n;
+       } else
+               strlcpy(ifname, argv[1], sizeof(ifname));
 
-       for (n = 2; n < argc; n++)
+       for (; n < argc; n++)
                if (wake(bpf, argv[n]))
                        warn("Cannot send Wake on LAN frame over `%s' to `%s'",
-                           argv[1], argv[n]);
+                           ifname, argv[n]);
        return EXIT_SUCCESS;
 }
-- 
Marc Balmer, Micro Systems, Wiesendamm 2a, Postfach, CH-4019 Basel, Switzerland
http://www.msys.ch/     http://www.vnode.ch/   "In God we trust, in C we code."


Home | Main Index | Thread Index | Old Index