tech-userlevel archive

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

Re: 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];

this should really be:

char ifname[IF_NAMESIZE];

> 
> -     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