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