--- a/ether-wake.c 2013-09-03 18:15:13.000000000 +0200 +++ b/ether-wake.c 2013-09-03 17:39:02.000000000 +0200 @@ -3,10 +3,10 @@ static char version_msg[] = "ether-wake.c: v1.09 11/12/2003 Donald Becker, http://www.scyld.com/"; static char brief_usage_msg[] = -"usage: ether-wake [-i ] [-p aa:bb:cc:dd[:ee:ff]] 00:11:22:33:44:55\n" +"usage: ether-wake -i [-p aa:bb:cc:dd[:ee:ff]] 00:11:22:33:44:55\n" " Use '-u' to see the complete set of options.\n"; static char usage_msg[] = -"usage: ether-wake [-i ] [-p aa:bb:cc:dd[:ee:ff]] 00:11:22:33:44:55\n" +"usage: ether-wake -i [-p aa:bb:cc:dd[:ee:ff]] 00:11:22:33:44:55\n" "\n" " This program generates and transmits a Wake-On-LAN (WOL)\n" " \"Magic Packet\", used for restarting machines that have been\n" @@ -22,7 +22,7 @@ " Options:\n" " -b Send wake-up packet to the broadcast address.\n" " -D Increase the debug level.\n" -" -i ifname Use interface IFNAME instead of the default 'eth0'.\n" +" -i ifname Use interface IFNAME.\n" " -p Append the four or six byte password PW to the packet.\n" " A password is only required for a few adapter types.\n" " The password may be specified in ethernet hex format\n" @@ -89,6 +89,9 @@ #include #include +#include "interface.h" +#include "sockets.h" + /* Grrr, no consistency between include versions. Enable this if setsockopt() isn't declared with your library. */ #if 0 @@ -110,20 +113,29 @@ static int get_fill(unsigned char *pkt, struct ether_addr *eaddr); static int get_wol_pw(const char *optarg); +typedef struct { + int s; + int verbose; + int pktsize; +} if_info; + +static int send_wol_packet(char *ifname, int s, int verbose, int pktsize); + +static int do_wake(struct interface *ife, void *cookie) { + if_info *info = (if_info *)cookie; + send_wol_packet(ife->name, info->s, info->verbose, info->pktsize); + return 0; +} + int main(int argc, char *argv[]) { - char *ifname = "eth0"; - int one = 1; /* True, for socket options. */ + char *ifname = NULL; int s; /* Raw socket */ int errflag = 0, verbose = 0, do_version = 0; int perm_failure = 0; - int i, c, pktsize; -#if defined(PF_PACKET) - struct sockaddr_ll whereto; -#else - struct sockaddr whereto; /* who to wake up */ -#endif + int c, pktsize; struct ether_addr eaddr; + if_info info; while ((c = getopt(argc, argv, "bDi:p:uvV")) != -1) switch (c) { @@ -177,13 +189,45 @@ pktsize = get_fill(outpack, &eaddr); + if (ifname == NULL) { + info.s = s; + info.verbose = verbose; + info.pktsize = pktsize; + + /* Create a channel to the NET kernel. */ + if ((sockets_open(0)) < 0) { + perror("socket"); + exit(1); + } + + return for_all_interfaces(do_wake, &info); + } + + return send_wol_packet(ifname, s, verbose, pktsize); +} + +/* Send a Wake-On-LAN (WOL) "Magic Packet" to Interface IFNAME using + Socket S with a packet size PKTSIZE. VERBOSE implies + verbosity. */ + +static int send_wol_packet(char *ifname, int s, int verbose, int pktsize) +{ + int i; + int one = 1; /* True, for socket options. */ +#if defined(PF_PACKET) + struct sockaddr_ll whereto; +#else + struct sockaddr whereto; /* who to wake up */ +#endif + /* Fill in the source address, if possible. The code to retrieve the local station address is Linux specific. */ if (! opt_no_src_addr) { struct ifreq if_hwaddr; - unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data; + char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data; - strcpy(if_hwaddr.ifr_name, ifname); + strncpy(if_hwaddr.ifr_name, ifname, IFNAMSIZ); + if_hwaddr.ifr_name[IFNAMSIZ-1] = '\0'; if (ioctl(s, SIOCGIFHWADDR, &if_hwaddr) < 0) { fprintf(stderr, "SIOCGIFHWADDR on %s failed: %s\n", ifname, strerror(errno)); @@ -220,7 +264,8 @@ #if defined(PF_PACKET) { struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ-1] = '\0'; if (ioctl(s, SIOCGIFINDEX, &ifr) == -1) { fprintf(stderr, "SIOCGIFINDEX on %s failed: %s\n", ifname, strerror(errno)); --- a/Makefile 2013-09-03 13:15:22.531951613 +0100 +++ b/Makefile 2013-09-03 13:24:29.659823455 +0100 @@ -188,6 +188,8 @@ mii-tool: $(NET_LIB) mii-tool.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ mii-tool.o $(NLIB) $(RESLIB) +ether-wake: $(NET_LIB) ether-wake.o + $(CC) $(LDFLAGS) -o ether-wake ether-wake.o $(NLIB) installbin: @echo @echo "######################################################" --- a/man/en_US/ether-wake.8 2013-09-03 13:15:22.576952098 +0100 +++ b/man/en_US/ether-wake.8 2013-09-03 13:14:55.270657575 +0100 @@ -49,7 +49,7 @@ Increase the Debug Level. .TP .B \-i ifname -Use interface ifname instead of the default "eth0". +Use interface ifname instead of sending a wake packet to all interfaces. .TP .B \-p passwd Append a four or six byte password to the packet. Only a few adapters