1dfda52d8SDavid du Colombier /* send wake-on-lan magic ethernet packet */
2dfda52d8SDavid du Colombier #include <u.h>
3dfda52d8SDavid du Colombier #include <libc.h>
4dfda52d8SDavid du Colombier #include <ip.h>
5dfda52d8SDavid du Colombier
6dfda52d8SDavid du Colombier enum {
7dfda52d8SDavid du Colombier Eaddrlen = 6, /* 48 bits */
8dfda52d8SDavid du Colombier };
9dfda52d8SDavid du Colombier
10dfda52d8SDavid du Colombier typedef struct Wolpack Wolpack;
11dfda52d8SDavid du Colombier struct Wolpack{
12dfda52d8SDavid du Colombier uchar magic[6];
13dfda52d8SDavid du Colombier uchar macs[16][Eaddrlen];
14dfda52d8SDavid du Colombier char pass[6+1];
15dfda52d8SDavid du Colombier };
16dfda52d8SDavid du Colombier
17dfda52d8SDavid du Colombier int verbose;
18dfda52d8SDavid du Colombier
19dfda52d8SDavid du Colombier void
usage(void)20dfda52d8SDavid du Colombier usage(void)
21dfda52d8SDavid du Colombier {
22dfda52d8SDavid du Colombier fprint(2, "usage: wol [-v] [-a dialstr] [-c password] macaddr\n");
23dfda52d8SDavid du Colombier exits("usage");
24dfda52d8SDavid du Colombier }
25dfda52d8SDavid du Colombier
26dfda52d8SDavid du Colombier void
fillmac(Wolpack * w,uchar * mac)27dfda52d8SDavid du Colombier fillmac(Wolpack *w, uchar *mac)
28dfda52d8SDavid du Colombier {
29dfda52d8SDavid du Colombier int i;
30dfda52d8SDavid du Colombier
31dfda52d8SDavid du Colombier for(i = 0; i < nelem(w->macs); i++)
32dfda52d8SDavid du Colombier memmove(w->macs[i], mac, Eaddrlen);
33dfda52d8SDavid du Colombier }
34dfda52d8SDavid du Colombier
35dfda52d8SDavid du Colombier void
dumppack(Wolpack * w)36dfda52d8SDavid du Colombier dumppack(Wolpack *w)
37dfda52d8SDavid du Colombier {
38dfda52d8SDavid du Colombier int i;
39dfda52d8SDavid du Colombier
40dfda52d8SDavid du Colombier print("packet: [\n");
41dfda52d8SDavid du Colombier print("\t%E\n", w->magic);
42dfda52d8SDavid du Colombier for(i = 0; i < nelem(w->macs); i++)
43dfda52d8SDavid du Colombier print("\t%E\n", w->macs[i]);
44dfda52d8SDavid du Colombier print("\t%6s\n", w->pass);
45dfda52d8SDavid du Colombier print("]\n");
46dfda52d8SDavid du Colombier }
47dfda52d8SDavid du Colombier
48dfda52d8SDavid du Colombier void
main(int argc,char * argv[])49dfda52d8SDavid du Colombier main(int argc, char* argv[])
50dfda52d8SDavid du Colombier {
51dfda52d8SDavid du Colombier int fd, nw;
52dfda52d8SDavid du Colombier char *argmac, *pass, *address;
53dfda52d8SDavid du Colombier uchar mac[Eaddrlen];
54dfda52d8SDavid du Colombier static Wolpack w = {
55dfda52d8SDavid du Colombier .magic { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }
56dfda52d8SDavid du Colombier };
57dfda52d8SDavid du Colombier
58dfda52d8SDavid du Colombier address = pass = nil;
59dfda52d8SDavid du Colombier fmtinstall('E', eipfmt);
60dfda52d8SDavid du Colombier
61dfda52d8SDavid du Colombier ARGBEGIN{
62dfda52d8SDavid du Colombier case 'a':
63dfda52d8SDavid du Colombier address = EARGF(usage());
64dfda52d8SDavid du Colombier break;
65dfda52d8SDavid du Colombier case 'c':
66dfda52d8SDavid du Colombier pass = EARGF(usage());
67dfda52d8SDavid du Colombier break;
68dfda52d8SDavid du Colombier case 'v':
69dfda52d8SDavid du Colombier verbose++;
70dfda52d8SDavid du Colombier break;
71dfda52d8SDavid du Colombier default:
72dfda52d8SDavid du Colombier usage();
73dfda52d8SDavid du Colombier }ARGEND
74dfda52d8SDavid du Colombier
75dfda52d8SDavid du Colombier if(argc != 1)
76dfda52d8SDavid du Colombier usage();
77dfda52d8SDavid du Colombier argmac = argv[0];
78dfda52d8SDavid du Colombier if(verbose)
79dfda52d8SDavid du Colombier print("mac is %s, pass is %s\n", argmac, pass);
80dfda52d8SDavid du Colombier
81dfda52d8SDavid du Colombier parseether(mac, argmac);
82dfda52d8SDavid du Colombier fillmac(&w, mac);
83dfda52d8SDavid du Colombier if(pass){
84dfda52d8SDavid du Colombier if(strlen(pass) > 6)
85*14cc0f53SDavid du Colombier sysfatal("password greater than 6 bytes");
86dfda52d8SDavid du Colombier strcpy(w.pass, pass);
87dfda52d8SDavid du Colombier }
88dfda52d8SDavid du Colombier if(verbose)
89dfda52d8SDavid du Colombier dumppack(&w);
90dfda52d8SDavid du Colombier
91dfda52d8SDavid du Colombier if(!address)
92dfda52d8SDavid du Colombier address = "udp!255.255.255.255!0";
93dfda52d8SDavid du Colombier
94dfda52d8SDavid du Colombier fd = dial(address, nil, nil, nil);
95dfda52d8SDavid du Colombier if(fd < 0)
96dfda52d8SDavid du Colombier sysfatal("%s: %r", address);
97dfda52d8SDavid du Colombier nw = write(fd, &w, sizeof w);
98dfda52d8SDavid du Colombier if(nw != sizeof w)
99dfda52d8SDavid du Colombier sysfatal("error sending: %r");
100dfda52d8SDavid du Colombier exits(0);
101dfda52d8SDavid du Colombier }
102