diff options
author | Mike Frysinger <vapier@gentoo.org> | 2005-05-11 03:59:53 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2005-05-11 03:59:53 +0000 |
commit | b662f0d58ba40cbbc1cca849fb6e8665688deb5e (patch) | |
tree | 9c39ef7e5ff639fac2b67a0b403385c345689c7d | |
parent | 348e84c202c4946d3694f130a6f81f61eb1d4b9e (diff) | |
download | busybox-w32-b662f0d58ba40cbbc1cca849fb6e8665688deb5e.tar.gz busybox-w32-b662f0d58ba40cbbc1cca849fb6e8665688deb5e.tar.bz2 busybox-w32-b662f0d58ba40cbbc1cca849fb6e8665688deb5e.zip |
import ether-wake applet by haveaniceday Bug 252
-rw-r--r-- | include/applets.h | 3 | ||||
-rw-r--r-- | include/usage.h | 13 | ||||
-rw-r--r-- | networking/Config.in | 6 | ||||
-rw-r--r-- | networking/Makefile.in | 62 | ||||
-rw-r--r-- | networking/ether-wake.c | 300 |
5 files changed, 352 insertions, 32 deletions
diff --git a/include/applets.h b/include/applets.h index 3f411c269..bc5b36ae3 100644 --- a/include/applets.h +++ b/include/applets.h | |||
@@ -188,6 +188,9 @@ | |||
188 | #ifdef CONFIG_ENV | 188 | #ifdef CONFIG_ENV |
189 | APPLET(env, env_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) | 189 | APPLET(env, env_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) |
190 | #endif | 190 | #endif |
191 | #ifdef CONFIG_ETHER_WAKE | ||
192 | APPLET_ODDNAME("ether-wake", etherwake_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER, ether_wake) | ||
193 | #endif | ||
191 | #ifdef CONFIG_EXPR | 194 | #ifdef CONFIG_EXPR |
192 | APPLET(expr, expr_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) | 195 | APPLET(expr, expr_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) |
193 | #endif | 196 | #endif |
diff --git a/include/usage.h b/include/usage.h index 316772ea2..c68ae2e0d 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -567,7 +567,7 @@ | |||
567 | #define eject_full_usage \ | 567 | #define eject_full_usage \ |
568 | "Eject specified DEVICE (or default /dev/cdrom).\n\n" \ | 568 | "Eject specified DEVICE (or default /dev/cdrom).\n\n" \ |
569 | "Options:\n" \ | 569 | "Options:\n" \ |
570 | "\tt" USAGE_EJECT_TRAYCLOSE "\tclose tray" | 570 | "\t-t" USAGE_EJECT_TRAYCLOSE "\tclose tray" |
571 | 571 | ||
572 | #define env_trivial_usage \ | 572 | #define env_trivial_usage \ |
573 | "[-iu] [-] [name=value]... [command]" | 573 | "[-iu] [-] [name=value]... [command]" |
@@ -578,6 +578,17 @@ | |||
578 | "\t-, -i\tstart with an empty environment\n" \ | 578 | "\t-, -i\tstart with an empty environment\n" \ |
579 | "\t-u\tremove variable from the environment" | 579 | "\t-u\tremove variable from the environment" |
580 | 580 | ||
581 | #define ether_wake_trivial_usage \ | ||
582 | "[-b] [-i iface] [-p aa:bb:cc:dd[:ee:ff]] MAC" | ||
583 | #define ether_wake_full_usage \ | ||
584 | "Send a magic packet to wake up sleeping machines.\n" \ | ||
585 | "MAC must be a station address (00:11:22:33:44:55) or\n" \ | ||
586 | " a hostname with a known 'ethers' entry.\n\n" \ | ||
587 | "Options:\n" \ | ||
588 | "\t-b\t\tSend wake-up packet to the broadcast address\n" \ | ||
589 | "\t-i iface\tUse interface ifname instead of the default \"eth0\"\n" \ | ||
590 | "\t-p pass\tAppend the four or six byte password PW to the packet\n" | ||
591 | |||
581 | #define expr_trivial_usage \ | 592 | #define expr_trivial_usage \ |
582 | "EXPRESSION" | 593 | "EXPRESSION" |
583 | #define expr_full_usage \ | 594 | #define expr_full_usage \ |
diff --git a/networking/Config.in b/networking/Config.in index a84427981..b6f8ee65d 100644 --- a/networking/Config.in +++ b/networking/Config.in | |||
@@ -18,6 +18,12 @@ config CONFIG_ARPING | |||
18 | help | 18 | help |
19 | Ping hosts by ARP packets | 19 | Ping hosts by ARP packets |
20 | 20 | ||
21 | config CONFIG_ETHER_WAKE | ||
22 | bool "ether-wake" | ||
23 | default n | ||
24 | help | ||
25 | Send a magic packet to wake up sleeping machines. | ||
26 | |||
21 | config CONFIG_FAKEIDENTD | 27 | config CONFIG_FAKEIDENTD |
22 | bool "fakeidentd" | 28 | bool "fakeidentd" |
23 | default n | 29 | default n |
diff --git a/networking/Makefile.in b/networking/Makefile.in index 778d0bade..d44a3d518 100644 --- a/networking/Makefile.in +++ b/networking/Makefile.in | |||
@@ -23,35 +23,36 @@ NETWORKING_DIR:=$(top_builddir)/networking/ | |||
23 | endif | 23 | endif |
24 | srcdir=$(top_srcdir)/networking | 24 | srcdir=$(top_srcdir)/networking |
25 | NETWORKING-y:= | 25 | NETWORKING-y:= |
26 | NETWORKING-$(CONFIG_ARPING) += arping.o | 26 | NETWORKING-$(CONFIG_ARPING) += arping.o |
27 | NETWORKING-$(CONFIG_FAKEIDENTD) += fakeidentd.o | 27 | NETWORKING-$(CONFIG_ETHER_WAKE) += ether-wake.o |
28 | NETWORKING-$(CONFIG_FTPGET) += ftpgetput.o | 28 | NETWORKING-$(CONFIG_FAKEIDENTD) += fakeidentd.o |
29 | NETWORKING-$(CONFIG_FTPPUT) += ftpgetput.o | 29 | NETWORKING-$(CONFIG_FTPGET) += ftpgetput.o |
30 | NETWORKING-$(CONFIG_HOSTNAME) += hostname.o | 30 | NETWORKING-$(CONFIG_FTPPUT) += ftpgetput.o |
31 | NETWORKING-$(CONFIG_HTTPD) += httpd.o | 31 | NETWORKING-$(CONFIG_HOSTNAME) += hostname.o |
32 | NETWORKING-$(CONFIG_IFCONFIG) += ifconfig.o | 32 | NETWORKING-$(CONFIG_HTTPD) += httpd.o |
33 | NETWORKING-$(CONFIG_IFUPDOWN) += ifupdown.o | 33 | NETWORKING-$(CONFIG_IFCONFIG) += ifconfig.o |
34 | NETWORKING-$(CONFIG_INETD) += inetd.o | 34 | NETWORKING-$(CONFIG_IFUPDOWN) += ifupdown.o |
35 | NETWORKING-$(CONFIG_IP) += ip.o | 35 | NETWORKING-$(CONFIG_INETD) += inetd.o |
36 | NETWORKING-$(CONFIG_IPCALC) += ipcalc.o | 36 | NETWORKING-$(CONFIG_IP) += ip.o |
37 | NETWORKING-$(CONFIG_IPADDR) += ipaddr.o | 37 | NETWORKING-$(CONFIG_IPCALC) += ipcalc.o |
38 | NETWORKING-$(CONFIG_IPLINK) += iplink.o | 38 | NETWORKING-$(CONFIG_IPADDR) += ipaddr.o |
39 | NETWORKING-$(CONFIG_IPROUTE) += iproute.o | 39 | NETWORKING-$(CONFIG_IPLINK) += iplink.o |
40 | NETWORKING-$(CONFIG_IPTUNNEL) += iptunnel.o | 40 | NETWORKING-$(CONFIG_IPROUTE) += iproute.o |
41 | NETWORKING-$(CONFIG_NAMEIF) += nameif.o | 41 | NETWORKING-$(CONFIG_IPTUNNEL) += iptunnel.o |
42 | NETWORKING-$(CONFIG_NC) += nc.o | 42 | NETWORKING-$(CONFIG_NAMEIF) += nameif.o |
43 | NETWORKING-$(CONFIG_NETSTAT) += netstat.o | 43 | NETWORKING-$(CONFIG_NC) += nc.o |
44 | NETWORKING-$(CONFIG_NSLOOKUP) += nslookup.o | 44 | NETWORKING-$(CONFIG_NETSTAT) += netstat.o |
45 | NETWORKING-$(CONFIG_PING) += ping.o | 45 | NETWORKING-$(CONFIG_NSLOOKUP) += nslookup.o |
46 | NETWORKING-$(CONFIG_PING6) += ping6.o | 46 | NETWORKING-$(CONFIG_PING) += ping.o |
47 | NETWORKING-$(CONFIG_ROUTE) += route.o | 47 | NETWORKING-$(CONFIG_PING6) += ping6.o |
48 | NETWORKING-$(CONFIG_TELNET) += telnet.o | 48 | NETWORKING-$(CONFIG_ROUTE) += route.o |
49 | NETWORKING-$(CONFIG_TELNETD) += telnetd.o | 49 | NETWORKING-$(CONFIG_TELNET) += telnet.o |
50 | NETWORKING-$(CONFIG_TFTP) += tftp.o | 50 | NETWORKING-$(CONFIG_TELNETD) += telnetd.o |
51 | NETWORKING-$(CONFIG_TRACEROUTE) += traceroute.o | 51 | NETWORKING-$(CONFIG_TFTP) += tftp.o |
52 | NETWORKING-$(CONFIG_VCONFIG) += vconfig.o | 52 | NETWORKING-$(CONFIG_TRACEROUTE) += traceroute.o |
53 | NETWORKING-$(CONFIG_WGET) += wget.o | 53 | NETWORKING-$(CONFIG_VCONFIG) += vconfig.o |
54 | NETWORKING-$(CONFIG_ZCIP) += zcip.o | 54 | NETWORKING-$(CONFIG_WGET) += wget.o |
55 | NETWORKING-$(CONFIG_ZCIP) += zcip.o | ||
55 | 56 | ||
56 | libraries-y+=$(NETWORKING_DIR)$(NETWORKING_AR) | 57 | libraries-y+=$(NETWORKING_DIR)$(NETWORKING_AR) |
57 | 58 | ||
@@ -59,7 +60,7 @@ needcrypt-y:= | |||
59 | needcrypt-$(CONFIG_FEATURE_HTTPD_AUTH_MD5) := y | 60 | needcrypt-$(CONFIG_FEATURE_HTTPD_AUTH_MD5) := y |
60 | 61 | ||
61 | ifeq ($(needcrypt-y),y) | 62 | ifeq ($(needcrypt-y),y) |
62 | LIBRARIES += -lcrypt | 63 | LIBRARIES += -lcrypt |
63 | endif | 64 | endif |
64 | 65 | ||
65 | $(NETWORKING_DIR)$(NETWORKING_AR): $(patsubst %,$(NETWORKING_DIR)%, $(NETWORKING-y)) | 66 | $(NETWORKING_DIR)$(NETWORKING_AR): $(patsubst %,$(NETWORKING_DIR)%, $(NETWORKING-y)) |
@@ -67,4 +68,3 @@ $(NETWORKING_DIR)$(NETWORKING_AR): $(patsubst %,$(NETWORKING_DIR)%, $(NETWORKING | |||
67 | 68 | ||
68 | $(NETWORKING_DIR)%.o: $(srcdir)/%.c | 69 | $(NETWORKING_DIR)%.o: $(srcdir)/%.c |
69 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< | 70 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< |
70 | |||
diff --git a/networking/ether-wake.c b/networking/ether-wake.c new file mode 100644 index 000000000..83ceece80 --- /dev/null +++ b/networking/ether-wake.c | |||
@@ -0,0 +1,300 @@ | |||
1 | /* | ||
2 | * ether-wake.c - Send a magic packet to wake up sleeping machines. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * Author: Donald Becker, http://www.scyld.com/"; http://www.scyld.com/wakeonlan.html | ||
10 | * Busybox port: Christian Volkmann <haveaniceday@online.de> | ||
11 | * Used version of ether-wake.c: v1.09 11/12/2003 Donald Becker, http://www.scyld.com/"; | ||
12 | */ | ||
13 | |||
14 | /* full usage according Donald Becker | ||
15 | * usage: ether-wake [-i <ifname>] [-p aa:bb:cc:dd[:ee:ff]] 00:11:22:33:44:55\n" | ||
16 | * | ||
17 | * This program generates and transmits a Wake-On-LAN (WOL)\n" | ||
18 | * \"Magic Packet\", used for restarting machines that have been\n" | ||
19 | * soft-powered-down (ACPI D3-warm state).\n" | ||
20 | * It currently generates the standard AMD Magic Packet format, with\n" | ||
21 | * an optional password appended.\n" | ||
22 | * | ||
23 | * The single required parameter is the Ethernet MAC (station) address\n" | ||
24 | * of the machine to wake or a host ID with known NSS 'ethers' entry.\n" | ||
25 | * The MAC address may be found with the 'arp' program while the target\n" | ||
26 | * machine is awake.\n" | ||
27 | * | ||
28 | * Options:\n" | ||
29 | * -b Send wake-up packet to the broadcast address.\n" | ||
30 | * -D Increase the debug level.\n" | ||
31 | * -i ifname Use interface IFNAME instead of the default 'eth0'.\n" | ||
32 | * -p <pw> Append the four or six byte password PW to the packet.\n" | ||
33 | * A password is only required for a few adapter types.\n" | ||
34 | * The password may be specified in ethernet hex format\n" | ||
35 | * or dotted decimal (Internet address)\n" | ||
36 | * -p 00:22:44:66:88:aa\n" | ||
37 | * -p 192.168.1.1\n"; | ||
38 | * | ||
39 | * | ||
40 | * This program generates and transmits a Wake-On-LAN (WOL) "Magic Packet", | ||
41 | * used for restarting machines that have been soft-powered-down | ||
42 | * (ACPI D3-warm state). It currently generates the standard AMD Magic Packet | ||
43 | * format, with an optional password appended. | ||
44 | * | ||
45 | * This software may be used and distributed according to the terms | ||
46 | * of the GNU Public License, incorporated herein by reference. | ||
47 | * Contact the author for use under other terms. | ||
48 | * | ||
49 | * This source file was originally part of the network tricks package, and | ||
50 | * is now distributed to support the Scyld Beowulf system. | ||
51 | * Copyright 1999-2003 Donald Becker and Scyld Computing Corporation. | ||
52 | * | ||
53 | * The author may be reached as becker@scyld, or C/O | ||
54 | * Scyld Computing Corporation | ||
55 | * 914 Bay Ridge Road, Suite 220 | ||
56 | * Annapolis MD 21403 | ||
57 | * | ||
58 | * Notes: | ||
59 | * On some systems dropping root capability allows the process to be | ||
60 | * dumped, traced or debugged. | ||
61 | * If someone traces this program, they get control of a raw socket. | ||
62 | * Linux handles this safely, but beware when porting this program. | ||
63 | * | ||
64 | * An alternative to needing 'root' is using a UDP broadcast socket, however | ||
65 | * doing so only works with adapters configured for unicast+broadcast Rx | ||
66 | * filter. That configuration consumes more power. | ||
67 | */ | ||
68 | |||
69 | |||
70 | #include <unistd.h> | ||
71 | #include <stdlib.h> | ||
72 | #include <stdio.h> | ||
73 | #include <errno.h> | ||
74 | #include <ctype.h> | ||
75 | #include <string.h> | ||
76 | |||
77 | #include <sys/socket.h> | ||
78 | #include <sys/types.h> | ||
79 | #include <sys/ioctl.h> | ||
80 | #include <features.h> | ||
81 | #include <netpacket/packet.h> | ||
82 | #include <net/ethernet.h> | ||
83 | #include <netdb.h> | ||
84 | #include <netinet/ether.h> | ||
85 | |||
86 | #ifdef __linux__ | ||
87 | #include <linux/if.h> | ||
88 | #endif | ||
89 | |||
90 | #include "busybox.h" | ||
91 | |||
92 | /* Note: PF_INET, SOCK_DGRAM, IPPROTO_UDP would allow SIOCGIFHWADDR to | ||
93 | * work as non-root, but we need SOCK_PACKET to specify the Ethernet | ||
94 | * destination address. | ||
95 | */ | ||
96 | #ifdef PF_PACKET | ||
97 | # define whereto_t sockaddr_ll | ||
98 | # define make_socket() socket(PF_PACKET, SOCK_RAW, 0) | ||
99 | #else | ||
100 | # define whereto_t sockaddr | ||
101 | # define make_socket() socket(AF_INET, SOCK_PACKET, SOCK_PACKET) | ||
102 | #endif | ||
103 | |||
104 | #ifdef DEBUG | ||
105 | # define bb_debug_msg(fmt, args...) fprintf(stderr, fmt, ## args) | ||
106 | void bb_debug_dump_packet(unsigned char *outpack, int pktsize) | ||
107 | { | ||
108 | int i; | ||
109 | printf("packet dump:\n"); | ||
110 | for (i = 0; i < pktsize; ++i) { | ||
111 | printf("%2.2x ", outpack[i]); | ||
112 | if (i % 20 == 19) printf("\n"); | ||
113 | } | ||
114 | printf("\n\n"); | ||
115 | } | ||
116 | #else | ||
117 | # define bb_debug_msg(fmt, args...) | ||
118 | # define bb_debug_dump_packet(outpack, pktsize) | ||
119 | #endif | ||
120 | |||
121 | static inline void get_dest_addr(const char *arg, struct ether_addr *eaddr); | ||
122 | static inline int get_fill(unsigned char *pkt, struct ether_addr *eaddr, int broadcast); | ||
123 | static inline int get_wol_pw(const char *ethoptarg, unsigned char *wol_passwd); | ||
124 | |||
125 | int etherwake_main(int argc, char *argv[]) | ||
126 | { | ||
127 | char *ifname = "eth0", *pass = NULL; | ||
128 | unsigned long flags; | ||
129 | unsigned char wol_passwd[6]; | ||
130 | int wol_passwd_sz = 0; | ||
131 | |||
132 | int s; /* Raw socket */ | ||
133 | int pktsize; | ||
134 | unsigned char outpack[1000]; | ||
135 | |||
136 | struct ether_addr eaddr; | ||
137 | struct whereto_t whereto; /* who to wake up */ | ||
138 | |||
139 | /* handle misc user options */ | ||
140 | flags = bb_getopt_ulflags(argc, argv, "bi:p:", &ifname, &pass); | ||
141 | if (optind == argc) | ||
142 | bb_show_usage(); | ||
143 | if (pass) | ||
144 | wol_passwd_sz = get_wol_pw(pass, wol_passwd); | ||
145 | |||
146 | /* create the raw socket */ | ||
147 | s = make_socket(); | ||
148 | if (s < 0) | ||
149 | bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket); | ||
150 | |||
151 | /* now that we have a raw socket we can drop root */ | ||
152 | setuid(getuid()); | ||
153 | |||
154 | /* look up the dest mac address */ | ||
155 | get_dest_addr(argv[optind], &eaddr); | ||
156 | |||
157 | /* fill out the header of the packet */ | ||
158 | pktsize = get_fill(outpack, &eaddr, flags /*& 1 [OPT_BROADCAST]*/); | ||
159 | |||
160 | bb_debug_dump_packet(outpack, pktsize); | ||
161 | |||
162 | /* Fill in the source address, if possible. */ | ||
163 | #ifdef __linux__ | ||
164 | { | ||
165 | struct ifreq if_hwaddr; | ||
166 | |||
167 | strcpy(if_hwaddr.ifr_name, ifname); | ||
168 | if (ioctl(s, SIOCGIFHWADDR, &if_hwaddr) < 0) | ||
169 | bb_perror_msg_and_die("SIOCGIFHWADDR on %s failed", ifname); | ||
170 | |||
171 | memcpy(outpack+6, if_hwaddr.ifr_hwaddr.sa_data, 6); | ||
172 | |||
173 | # ifdef DEBUG | ||
174 | { | ||
175 | unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data; | ||
176 | printf("The hardware address (SIOCGIFHWADDR) of %s is type %d " | ||
177 | "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n\n", ifname, | ||
178 | if_hwaddr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1], | ||
179 | hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); | ||
180 | } | ||
181 | # endif | ||
182 | } | ||
183 | #endif /* __linux__ */ | ||
184 | |||
185 | bb_debug_dump_packet(outpack, pktsize); | ||
186 | |||
187 | /* append the password if specified */ | ||
188 | if (wol_passwd_sz > 0) { | ||
189 | memcpy(outpack+pktsize, wol_passwd, wol_passwd_sz); | ||
190 | pktsize += wol_passwd_sz; | ||
191 | } | ||
192 | |||
193 | bb_debug_dump_packet(outpack, pktsize); | ||
194 | |||
195 | /* This is necessary for broadcasts to work */ | ||
196 | if (flags /*& 1 [OPT_BROADCAST]*/) { | ||
197 | int one = 1; | ||
198 | if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (void *)&one, sizeof(one)) < 0) | ||
199 | bb_perror_msg("SO_BROADCAST"); | ||
200 | } | ||
201 | |||
202 | #if defined(PF_PACKET) | ||
203 | { | ||
204 | struct ifreq ifr; | ||
205 | strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); | ||
206 | if (ioctl(s, SIOCGIFINDEX, &ifr) == -1) | ||
207 | bb_perror_msg_and_die("SIOCGIFINDEX"); | ||
208 | memset(&whereto, 0, sizeof(whereto)); | ||
209 | whereto.sll_family = AF_PACKET; | ||
210 | whereto.sll_ifindex = ifr.ifr_ifindex; | ||
211 | /* The manual page incorrectly claims the address must be filled. | ||
212 | We do so because the code may change to match the docs. */ | ||
213 | whereto.sll_halen = ETH_ALEN; | ||
214 | memcpy(whereto.sll_addr, outpack, ETH_ALEN); | ||
215 | } | ||
216 | #else | ||
217 | whereto.sa_family = 0; | ||
218 | strcpy(whereto.sa_data, ifname); | ||
219 | #endif | ||
220 | |||
221 | if (sendto(s, outpack, pktsize, 0, (struct sockaddr *)&whereto, sizeof(whereto)) < 0) | ||
222 | bb_perror_msg(bb_msg_write_error); | ||
223 | |||
224 | close(s); | ||
225 | |||
226 | return EXIT_SUCCESS; | ||
227 | } | ||
228 | |||
229 | /* Convert the host ID string to a MAC address. | ||
230 | * The string may be a: | ||
231 | * Host name | ||
232 | * IP address string | ||
233 | * MAC address string | ||
234 | */ | ||
235 | static inline void get_dest_addr(const char *hostid, struct ether_addr *eaddr) | ||
236 | { | ||
237 | struct ether_addr *eap; | ||
238 | |||
239 | eap = ether_aton(hostid); | ||
240 | if (eap) { | ||
241 | *eaddr = *eap; | ||
242 | bb_debug_msg("The target station address is %s\n\n", ether_ntoa(eaddr)); | ||
243 | } else if (ether_hostton(hostid, eaddr) == 0) { | ||
244 | bb_debug_msg("Station address for hostname %s is %s\n\n", hostid, ether_ntoa(eaddr)); | ||
245 | } else | ||
246 | bb_show_usage(); | ||
247 | } | ||
248 | |||
249 | static inline int get_fill(unsigned char *pkt, struct ether_addr *eaddr, int broadcast) | ||
250 | { | ||
251 | int offset, i; | ||
252 | unsigned char *station_addr = eaddr->ether_addr_octet; | ||
253 | |||
254 | if (broadcast) | ||
255 | memset(pkt+0, 0xff, 6); | ||
256 | else | ||
257 | memcpy(pkt, station_addr, 6); | ||
258 | memcpy(pkt+6, station_addr, 6); | ||
259 | pkt[12] = 0x08; /* Or 0x0806 for ARP, 0x8035 for RARP */ | ||
260 | pkt[13] = 0x42; | ||
261 | offset = 14; | ||
262 | |||
263 | memset(pkt+offset, 0xff, 6); | ||
264 | offset += 6; | ||
265 | |||
266 | for (i = 0; i < 16; ++i) { | ||
267 | memcpy(pkt+offset, station_addr, 6); | ||
268 | offset += 6; | ||
269 | } | ||
270 | |||
271 | return offset; | ||
272 | } | ||
273 | |||
274 | static inline int get_wol_pw(const char *ethoptarg, unsigned char *wol_passwd) | ||
275 | { | ||
276 | int passwd[6]; | ||
277 | int byte_cnt, i; | ||
278 | |||
279 | /* handle MAC format */ | ||
280 | byte_cnt = sscanf(ethoptarg, "%2x:%2x:%2x:%2x:%2x:%2x", | ||
281 | &passwd[0], &passwd[1], &passwd[2], | ||
282 | &passwd[3], &passwd[4], &passwd[5]); | ||
283 | /* handle IP format */ | ||
284 | if (byte_cnt < 4) | ||
285 | byte_cnt = sscanf(ethoptarg, "%d.%d.%d.%d", | ||
286 | &passwd[0], &passwd[1], &passwd[2], &passwd[3]); | ||
287 | if (byte_cnt < 4) { | ||
288 | bb_error_msg("Unable to read the Wake-On-LAN pass"); | ||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | for (i = 0; i < byte_cnt; ++i) | ||
293 | wol_passwd[i] = passwd[i]; | ||
294 | |||
295 | bb_debug_msg("password: %2.2x %2.2x %2.2x %2.2x (%d)\n\n", | ||
296 | wol_passwd[0], wol_passwd[1], wol_passwd[2], wol_passwd[3], | ||
297 | byte_cnt); | ||
298 | |||
299 | return byte_cnt; | ||
300 | } | ||